﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Diagnostics;
using System.Reflection;
using LTKJ.DataBase;
//using System.Threading;
using System.Globalization;
using System.Threading;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Windows.Forms.DataVisualization.Charting;
using System.Drawing;
using System.Text.RegularExpressions;
using Test;
using System.Runtime.InteropServices;
using System.Configuration;
using System.Collections;
using System.Drawing.Drawing2D;
using static System.Net.Mime.MediaTypeNames;
using Application = System.Windows.Forms.Application;
using System.Net.WebSockets;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ProgressBar;
using System.ComponentModel.Design.Serialization;
using static System.Collections.Specialized.BitVector32;
using System.Security.Policy;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace LTKJ.RTU
{
    public partial class FrmMain20250724 : Form
    {
        #region 公共变量

        //获取App.config配置参数
        public string strConnection = System.Configuration.ConfigurationManager.ConnectionStrings["OracleConnection"].ToString();

        Thread tRead = null;
        DataTable dtDevice = null;

        private Dictionary<string, string> oilStatus = new Dictionary<string, string>();
        List<string> cmdList = new List<string>();

        private System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
        private System.Windows.Forms.Timer timer2 = new System.Windows.Forms.Timer();
        private System.Windows.Forms.Timer timer3 = new System.Windows.Forms.Timer();
        Socket Socket = null;
        private static Dictionary<string, TcpClient> Dic_tcp = new Dictionary<string, TcpClient>();
        private Dictionary<IntPtr, Session> serverSessionPool = new Dictionary<IntPtr, Session>();
        int port = 0;
        Dictionary<string, string> dicInit = new Dictionary<string, string>();//key 为设备serial，value为设备名
        private static object locker = new object();
        private string pw = "12 34 56 78 87 65 43 21 11 22 33 44 55 66 77 88";
        private string randomStr = "12 34 56 78";
        public int seq = 1;
        delegate void MyDelegate(string message);
        private MyDelegate myDeleteage;

        //websocket   
        private static HttpListener listener = new HttpListener();
        private static ConcurrentDictionary<string, WebSocket> webSockets = new ConcurrentDictionary<string, WebSocket>();
        // 存储上报类型
        Dictionary<string, string> reportTypeDic = new Dictionary<string, string>();
        #endregion

        /// <summary>
        /// 窗体初始化
        /// </summary>
        public FrmMain20250724()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 窗体加载事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void FrmMain_Load(object sender, EventArgs e)
        {
            try
            {
                portTextbox.Text = "7001";
                //   Text += "[Port:" + intPort + "]";
                icnSys.Text = Text;
                //窗体控件事件

                tsbtnClose.Click += TsbtnClose_Click;

                //最小化通知区域和退出
                FormClosing += FrmMain_FormClosing;         //关闭窗体前事件
                SizeChanged += FrmMain_SizeChanged;         //窗体大小改变事件                
                tsbtnExit.Click += TsbtnExit_Click;         //右键菜单退出事件
                icnSys.Click += IcnSys_Click;               //点击图标事件

                //string str = " 80 01 00 05 09 90 70 56 09 62 00 68 00 7d 02 10 00 57 09 ";
                //string result = zhuanYi(str);

                // Test();

                //  test1();
                myDeleteage = ShowMessage;

                dtDevice = DbHelper.GetDataTable("select car_id node_id,card_id node_name,lock_logo as rtu_id,1 as type from sys_car ");

                reortDicInit();

                Init();

                //指定不再捕获对错误线程的调用
                Control.CheckForIllegalCrossThreadCalls = false;

                Timer1_Tick(null, null);

                //定时更新设备信息 - 改为异步执行
                timer1.Interval = 1000 * 30;
                timer1.Tick += Timer1_Tick;
                timer1.Start();

                //定时任务 控制指令查询
                System.Windows.Forms.Timer timer2 = new System.Windows.Forms.Timer();
                timer2.Interval = 1000 * 2;
                timer2.Tick += SysControl;
                timer2.Start();

                //启动websocket服务
                //await StartServerAsync();

                //定时采集参数数据
                timer3.Interval = 1000 * 60 * 10;
                timer3.Tick += arg_Collect;
                timer3.Start();

                // 添加心跳检测定时器 - 每2分钟检查一次
                System.Windows.Forms.Timer heartBeatTimer = new System.Windows.Forms.Timer();
                heartBeatTimer.Interval = 1000 * 60 * 2;
                heartBeatTimer.Tick += HeartBeatCheck;
                heartBeatTimer.Start();

            }
            catch (Exception ex)
            {
                ShowMessageInWindow(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message);
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message);//将出错信息写入错误日志           
            }
        }

        public void test1()
        {
            string data = "7E0200004A099070560962003C0000010000000003026DC7240666576000000000013224082315021501040000002133262A4D30302C32392C313033393231303830303231383036263230303030303030303030302623067E";
            string lengthStr = data.Substring(6, 4);
            int length = Convert.ToInt32(lengthStr, 16);//消息体长度，不包含校验码及帧尾标识符以及消息头的所有内容
            string teminalSeq = data.Substring(10, 12); //终端序列号
            string seq = data.Substring(22, 4);//流水号  
            string a = "";
        }

        //代码转义
        private string zhuanYi(string sourceStr)
        {
            byte[] source = Common.HexStringToByteArray(sourceStr);
            byte flag1 = 126;
            byte flag2 = 125;

            List<byte> result = new List<byte>();
            for (int i = 0; i < source.Length; i++)
            {
                byte temp = source[i];
                if (temp == flag1)
                {
                    byte b1 = 125;
                    byte b2 = 2;
                    result.Add(b1);
                    result.Add(b2);
                }
                else if (temp == flag2)
                {
                    byte b1 = 125;
                    byte b2 = 1;
                    result.Add(b1);
                    result.Add(b2);
                }
                else
                {
                    result.Add(temp);
                }
            }
            byte[] resultArray = result.ToArray(); // 将列表转换为数组
            string res = Common.ByteArrayToHexString(resultArray);
            return res;
        }

        private void arg_Collect(object sender, EventArgs e)
        {
            // 使用foreach循环遍历DataTable中的所有行
            foreach (DataRow row in dtDevice.Rows)
            {
                string rtuId = row["rtu_id"].ToString();
                if (rtuId.Length == 12)
                {
                    Session session = getSessionByRtuId(rtuId);
                    if (session != null)
                    {
                        string cmdReportId = "1FFF";
                        string cmdMessage = "11 06 03 04 05 08 09 0A 0B 17 18 19 1A 1B 1C 26  34 01";
                        int messageLen = cmdMessage.Replace(" ", "").Length / 2;//消息体长度
                        string cmdFull = "";
                        int reportId = Convert.ToInt32(cmdReportId, 16);
                        cmdFull = "03 12" + DEC_to_HEX(messageLen.ToString()) + rtuId + DEC_to_HEX(reportId);//消息头
                        cmdFull = cmdFull + cmdMessage;
                        cmdFull = cmdFull + SunCheck(cmdFull);
                        cmdFull = cmdFull.Replace("7E", "7D02").Replace("7D", "7D01");
                        cmdFull = "7E" + cmdFull + "7E";
                        byte[] data = Common.HexStringToByteArray(cmdFull);
                        cmdFull = Common.ByteArrayToHexString(data, 0, data.Length);
                        ShowMessageInWindow("发送读取基本参数指令：" + cmdFull);
                        Send(session.SockeClient, data, session.IP);

                        //查找分锁
                        cmdReportId = "2FFF";
                        cmdMessage = "01 02 01 00 ";
                        messageLen = cmdMessage.Replace(" ", "").Length / 2;//消息体长度
                        cmdFull = "";
                        reportId = Convert.ToInt32(cmdReportId, 16);
                        cmdFull = "03 20" + DEC_to_HEX(messageLen.ToString()) + rtuId + DEC_to_HEX(reportId);//消息头
                        cmdFull = cmdFull + cmdMessage;
                        cmdFull = cmdFull + SunCheck(cmdFull);
                        cmdFull = cmdFull.Replace("7E", "7D02").Replace("7D", "7D01");
                        cmdFull = "7E" + cmdFull + "7E";
                        data = Common.HexStringToByteArray(cmdFull);
                        cmdFull = Common.ByteArrayToHexString(data, 0, data.Length);
                        ShowMessageInWindow("发送读取周边锁指令：" + cmdFull);
                        Send(session.SockeClient, data, session.IP);

                        //获得绑卡信息
                        cmdReportId = "3FFF";
                        cmdMessage = "33 2a 4d 30 37 2c 30 30 2c 23 ";
                        messageLen = cmdMessage.Replace(" ", "").Length / 2;//消息体长度
                        cmdFull = "";
                        reportId = Convert.ToInt32(cmdReportId, 16);
                        cmdFull = "89 00" + DEC_to_HEX(messageLen.ToString()) + rtuId + DEC_to_HEX(reportId);//消息头
                        cmdFull = cmdFull + cmdMessage;
                        cmdFull = cmdFull + SunCheck(cmdFull);
                        cmdFull = cmdFull.Replace("7E", "7D02").Replace("7D", "7D01");
                        cmdFull = "7E" + cmdFull + "7E";
                        data = Common.HexStringToByteArray(cmdFull);
                        cmdFull = Common.ByteArrayToHexString(data, 0, data.Length);
                        ShowMessageInWindow("发送获得绑卡信息指令：" + cmdFull);
                        Send(session.SockeClient, data, session.IP);

                    }

                }

            }
        }

        public async Task StartServerAsync()
        {
            //listener.Prefixes.Add($"ws://{Host}:{PortNumber}/");
            listener.Prefixes.Add("http://192.168.21.90:9000/websocket/");
            listener.Start();
            ShowMessageInWindow("WebSocket server started at ws://127.0.0.1:9000");

            while (true)
            {
                HttpListenerContext context = await listener.GetContextAsync();
                if (context.Request.IsWebSocketRequest)
                {
                    // 等待异步操作完成并获取 HttpListenerWebSocketContext
                    var webSocketContextTask = context.AcceptWebSocketAsync(subProtocol: null);
                    HttpListenerWebSocketContext webSocketContext = await webSocketContextTask;

                    // 从 HttpListenerWebSocketContext 中获取 WebSocket 对象
                    WebSocket webSocket = webSocketContext.WebSocket;
                    string clientId = context.Request.UserHostAddress; // Using client IP as clientId for simplicity

                    // Add the new WebSocket to the dictionary
                    webSockets.TryAdd(clientId, webSocket);
                    HandleWebSocket(clientId, webSocket);
                    //await Task.Delay(5000);
                    //await SendMessageToClientAsync(clientId,"已经接入websocket服务端");
                }
                else
                {
                    context.Response.StatusCode = 400;
                    context.Response.Close();
                }
            }
        }

        private async void HandleWebSocket(string clientId, WebSocket webSocket)
        {
            try
            {

                while (webSocket.State == WebSocketState.Open)
                {
                    byte[] buffer = new byte[4096];
                    var cancellationToken = CancellationToken.None;
                    var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), cancellationToken);
                    string utf8String = Encoding.UTF8.GetString(buffer, 0, result.Count);
                    ShowMessageInWindow("收到客户端 " + clientId + " 消息：" + utf8String);

                    if (result.MessageType == WebSocketMessageType.Close)
                    {
                        await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", cancellationToken);
                        break;
                    }

                    // Echo the received message back to the client
                    //await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, cancellationToken);
                }
            }
            catch (Exception e)
            {
                ShowMessageInWindow("Error: " + e.Message);
            }
            finally
            {
                // Remove the WebSocket from the dictionary
                webSockets.TryRemove(clientId, out WebSocket removedSocket);
                ShowMessageInWindow("Connection closed for client " + clientId);
            }
        }

        // Method to send data to a specific client
        public async Task SendMessageToClientAsync(string clientId, string message)
        {
            if (webSockets.TryGetValue(clientId, out WebSocket webSocket))
            {
                if (webSocket.State == WebSocketState.Open)
                {
                    byte[] buffer = Encoding.UTF8.GetBytes(message);
                    await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, buffer.Length), WebSocketMessageType.Text, true, CancellationToken.None);
                }
            }
        }


        private void Timer1_Tick(object sender, EventArgs e)
        {
            try
            {
                //更新设备信息 - 使用异步执行，避免阻塞UI
                ThreadPool.QueueUserWorkItem(new WaitCallback(Timer1_TickAsync), null);
                
                // UI相关操作保持在UI线程
                int count = getTextBoxCount(txtMessage.Text);
                if (count > 500)
                {
                    try
                    {
                        txtMessage.Text = "";
                    }
                    catch (Exception ex)
                    {
                        ShowMessageInWindow("清理消息文本异常：" + ex.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                ShowMessageInWindow(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message);
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message);//将出错信息写入错误日志         
            }
        }
        
        /// <summary>
        /// 异步执行定时任务
        /// </summary>
        /// <param name="state"></param>
        private void Timer1_TickAsync(object state)
        {
            try
            {
                //更新设备信息
                dtDevice = DbHelper.GetDataTable("select car_id node_id,card_id node_name,lock_logo as rtu_id,1 as type from sys_car union all SELECT id node_id,name node_name,lock_logo AS rtu_id,0 AS TYPE FROM TANK_FARM");
                
                //检查链路是否超时断开
                checkSocketTimeOut();
            }
            catch (Exception ex)
            {
                ShowMessageInWindow("异步定时任务异常：" + ex.Message);
                Common.WriteErrorLog("Timer1_TickAsync异常：" + ex.Message);
            }
        }

        /// <summary>
        /// 通过查询链路最后一条数据的时间来判断socket 是否断开 并断开连接
        /// </summary>
        public void checkSocketTimeOut()
        {
            List<Session> expiredSessions = new List<Session>();
            int timeoutMinutes = 10; // 增加超时时间到10分钟
            
            try
            {
                // 先收集需要超时的会话，包含完整的Session信息
                lock (locker)
                {
                    DateTime now = DateTime.Now;
                    List<IntPtr> keysToRemove = new List<IntPtr>();
                    
                    foreach (var kvp in serverSessionPool)
                    {
                        try
                        {
                            IntPtr key = kvp.Key;
                            Session session = kvp.Value;
                            
                            if (session == null)
                            {
                                keysToRemove.Add(key);
                                continue;
                            }
                            
                            // 检查Socket是否仍然有效
                            if (session.SockeClient == null || !session.SockeClient.Connected)
                            {
                                expiredSessions.Add(session);
                                continue;
                            }
                            
                            // 检查超时
                            TimeSpan t = now - session.LastRecDataTime;
                            if (t.TotalMinutes > timeoutMinutes)
                            {
                                expiredSessions.Add(session);
                            }
                        }
                        catch (Exception ex)
                        {
                            ShowMessageInWindow($"检查会话超时时异常：{ex.Message}");
                            Common.WriteErrorLog($"检查会话超时时异常：{ex.Message}");
                        }
                    }
                    
                    // 移除无效的会话
                    foreach (IntPtr key in keysToRemove)
                    {
                        serverSessionPool.Remove(key);
                    }
                }

                // 在锁外处理超时的会话
                foreach (Session session in expiredSessions)
                {
                    try
                    {
                        if (session != null)
                        {
                            ShowMessageInWindow($"关闭超时连接：{session.DeviceName}({session.IP})");
                            
                            // 安全关闭Socket
                            if (session.SockeClient != null)
                            {
                                SafeClose(session.SockeClient);
                            }
                            
                            // 从会话池中移除
                            removeSocketClient(session.SockeClient.Handle);
                        }
                    }
                    catch (Exception ex)
                    {
                        ShowMessageInWindow($"关闭超时连接异常：{ex.Message}");
                        Common.WriteErrorLog($"关闭超时连接异常：{ex.Message}");
                    }
                }
                
                // 记录活跃连接数
                int activeConnections = 0;
                lock (locker)
                {
                    activeConnections = serverSessionPool.Count;
                }
                
                if (expiredSessions.Count > 0)
                {
                    ShowMessageInWindow($"超时检查完成，关闭了{expiredSessions.Count}个连接，当前活跃连接数：{activeConnections}");
                }
            }
            catch (Exception ex)
            {
                ShowMessageInWindow("checkSocketTimeOut异常：" + ex.Message);
                Common.WriteErrorLog("checkSocketTimeOut异常：" + ex.Message);
            }
        }

        private void SysControl1(object sender, EventArgs e)
        {
            try
            {
                DataTable dt = Common.GetTableData("SYS_CONTROL", "and mark=0", "", "id", "asc");
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    string opId = "";
                    string deviceId = "";
                    string deviceName = "";
                    try
                    {
                        opId = dt.Rows[i]["id"].ToString();
                        deviceId = dt.Rows[i]["device_id"].ToString();
                        deviceName = dt.Rows[i]["device_name"].ToString();
                        string cmdType = dt.Rows[i]["CMD_TYPE"].ToString();
                        string cmdTypeName = dt.Rows[i]["CMD_TYPE_NAME"].ToString();
                        string cmdValue = dt.Rows[i]["cmd_value"].ToString();
                        string stimeStr = dt.Rows[i]["stime"].ToString();
                        string rtuId = dt.Rows[i]["rtu_Id"].ToString();
                        string cmdReportId = dt.Rows[i]["CMD_REPORT_ID"].ToString();
                        cmdReportId = DEC_to_2HEX(cmdReportId);
                        DateTime stime = Convert.ToDateTime(stimeStr);
                        string jsonStr = dt.Rows[i]["json_str"].ToString();
                        JObject jsonObject = JsonConvert.DeserializeObject<JObject>(jsonStr);


                        Session session = getSessionByRtuId(rtuId);
                        if (session == null || session.SockeClient == null || !session.SockeClient.Connected)
                        {
                            continue;
                        }

                    }
                    catch (Exception ex)
                    {
                        ShowMessageInWindow("发送控制指令异常：" + ex.Message);
                    }
                }

            }
            catch (Exception ex)
            {
                ShowMessageInWindow("发送控制指令异常：" + ex.Message);
            }
        }

        private void SysControl(object sender, EventArgs e)
        {
            try
            {
                DataTable dt = Common.GetTableData("SYS_CONTROL", "and mark=0", "", "id", "asc");
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    string opId = "";
                    string deviceId = "";
                    string deviceName = "";
                    try
                    {
                        opId = dt.Rows[i]["id"].ToString();
                        deviceId = dt.Rows[i]["device_id"].ToString();
                        deviceName = dt.Rows[i]["device_name"].ToString();
                        string cmdType = dt.Rows[i]["CMD_TYPE"].ToString();
                        string cmdTypeName = dt.Rows[i]["CMD_TYPE_NAME"].ToString();
                        string cmdValue = dt.Rows[i]["cmd_value"].ToString();
                        string stimeStr = dt.Rows[i]["stime"].ToString();
                        string rtuId = dt.Rows[i]["rtu_Id"].ToString();
                        string cmdReportId = dt.Rows[i]["CMD_REPORT_ID"].ToString();
                        cmdReportId = DEC_to_2HEX(cmdReportId);
                        DateTime stime = Convert.ToDateTime(stimeStr);
                        string lockId = dt.Rows[i]["lock_id"].ToString();
                        string lockSeq = dt.Rows[i]["lock_seq"].ToString();



                        TimeSpan tSpan = DateTime.Now - stime;
                        if (tSpan.TotalMinutes > 5)
                        {
                            Common.ExecuteNonQuery("update sys_control set status='失败,指令超时',mark=1 where id='" + opId + "'");
                            continue;
                        }

                        Session session = getSessionByRtuId(rtuId);
                        if (session == null || session.SockeClient == null || !session.SockeClient.Connected)
                        {
                            continue;
                        }
                        //施解封
                        if ("1".Equals(cmdType) || "2".Equals(cmdType))
                        {
                            cmdValue = cmdValue.Replace(" ", "");
                            int temp = Convert.ToInt32(cmdValue, 2);
                            string value16 = DEC_to_HEX(temp);
                            string cmd = "01 25 02 " + value16;  //消息体
                            cmd = cmd.Replace(" ", "");
                            int length = cmd.Length / 2;  //消息体长度
                                                          // int reportId = int.Parse(cmdReportId);
                            int reportId = Convert.ToInt32(cmdReportId, 16);
                            cmd = "03 10" + DEC_to_HEX(length) + rtuId + DEC_to_HEX(reportId) + cmd;
                            cmd = cmd + SunCheck(cmd);
                            cmd = cmd.Replace("7E", "7D02").Replace("7D", "7D01");
                            cmd = "7E" + cmd + "7E";
                            byte[] data = Common.HexStringToByteArray(cmd);
                            cmd = Common.ByteArrayToHexString(data, 0, data.Length);
                            ShowMessageInWindow("发送指令：" + cmd);
                            Send(session.SockeClient, data, session.IP);
                        }
                        //绑锁
                        if ("5".Equals(cmdType))
                        {
                            string jsonStr = dt.Rows[i]["json_str"].ToString();
                            JObject jsonObject = JsonConvert.DeserializeObject<JObject>(jsonStr);
                            JArray cmdData = (JArray)jsonObject["cmdData"];
                            // 
                            string cmdMessage = "";
                            int count = 0;
                            bool isLock1 = false;
                            bool isLock2 = false;
                            bool isLock3 = false;
                            bool isLock4 = false;
                            bool isLock5 = false;
                            bool isLock6 = false;
                            bool isLock7 = false;
                            bool isLock8 = false;
                            bool isLock9 = false;
                            bool isLock10 = false;
                            bool isLock11 = false;
                            bool isLock12 = false;
                            foreach (JObject cmdJson in cmdData)
                            {

                                int cmdIndex = (int)cmdJson["cmdIndex"];
                                string cmdName = (string)cmdJson["cmdName"];
                                string cmdIndexStr = DEC_to_2HEX(cmdIndex.ToString());

                                //绑1号锁
                                if (cmdIndex == 23)
                                {
                                    isLock1 = true;
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = "";
                                    if (value == "00")
                                    {
                                        valueStr = "00";
                                    }
                                    else
                                    {
                                        valueStr = StringToUtf8Hex(value);
                                    }

                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                                //绑2号锁
                                if (cmdIndex == 24)
                                {
                                    isLock2 = true;
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = "";
                                    if (value == "00")
                                    {
                                        valueStr = "00";
                                    }
                                    else
                                    {
                                        valueStr = StringToUtf8Hex(value);
                                    }
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                                //绑3号锁
                                if (cmdIndex == 25)
                                {
                                    isLock3 = true;
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = "";
                                    if (value == "00")
                                    {
                                        valueStr = "00";
                                    }
                                    else
                                    {
                                        valueStr = StringToUtf8Hex(value);
                                    }
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                                //绑4号锁
                                if (cmdIndex == 26)
                                {
                                    isLock4 = true;
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = "";
                                    if (value == "00")
                                    {
                                        valueStr = "00";
                                    }
                                    else
                                    {
                                        valueStr = StringToUtf8Hex(value);
                                    }
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                                //绑5号锁
                                if (cmdIndex == 27)
                                {
                                    isLock5 = true;
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = "";
                                    if (value == "00")
                                    {
                                        valueStr = "00";
                                    }
                                    else
                                    {
                                        valueStr = StringToUtf8Hex(value);
                                    }
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                                //绑6号锁
                                if (cmdIndex == 28)
                                {
                                    isLock6 = true;
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = "";
                                    if (value == "00")
                                    {
                                        valueStr = "00";
                                    }
                                    else
                                    {
                                        valueStr = StringToUtf8Hex(value);
                                    }
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                            }
                            count = count + 6;
                            cmdMessage = cmdMessage + DEC_to_2HEX("29".ToString()) + DEC_to_2HEX(1.ToString()) + "00";
                            cmdMessage = cmdMessage + DEC_to_2HEX("30".ToString()) + DEC_to_2HEX(1.ToString()) + "00";
                            cmdMessage = cmdMessage + DEC_to_2HEX("31".ToString()) + DEC_to_2HEX(1.ToString()) + "00";
                            cmdMessage = cmdMessage + DEC_to_2HEX("32".ToString()) + DEC_to_2HEX(1.ToString()) + "00";
                            cmdMessage = cmdMessage + DEC_to_2HEX("33".ToString()) + DEC_to_2HEX(1.ToString()) + "00";
                            cmdMessage = cmdMessage + DEC_to_2HEX("34".ToString()) + DEC_to_2HEX(1.ToString()) + "00";

                            cmdMessage = DEC_to_2HEX(count.ToString()) + cmdMessage;
                            int messageLen = cmdMessage.Replace(" ", "").Length / 2;//消息体长度
                            string cmdFull = "";
                            int reportId = Convert.ToInt32(cmdReportId, 16);
                            cmdFull = "03 10" + DEC_to_HEX(messageLen.ToString()) + rtuId + DEC_to_HEX(reportId);//消息头
                            cmdFull = cmdFull + cmdMessage;
                            cmdFull = cmdFull + SunCheck(cmdFull);
                            cmdFull = cmdFull.Replace("7E", "7D02").Replace("7D", "7D01");
                            cmdFull = "7E" + cmdFull + "7E";
                            byte[] data = Common.HexStringToByteArray(cmdFull);
                            cmdFull = Common.ByteArrayToHexString(data, 0, data.Length);
                            ShowMessageInWindow("发送指令：" + cmdFull);
                            Send(session.SockeClient, data, session.IP);
                        }

                        //配置基本参数
                        if ("3".Equals(cmdType))
                        {
                            string jsonStr = dt.Rows[i]["json_str"].ToString();
                            JObject jsonObject = JsonConvert.DeserializeObject<JObject>(jsonStr);
                            JArray cmdData = (JArray)jsonObject["cmdData"];
                            // 
                            string cmdMessage = "";
                            int count = 0;
                            foreach (JObject cmdJson in cmdData)
                            {

                                int cmdIndex = (int)cmdJson["cmdIndex"];
                                string cmdName = (string)cmdJson["cmdName"];
                                string cmdIndexStr = DEC_to_2HEX(cmdIndex.ToString());

                                if (cmdIndex == 1)
                                {
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = value;
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }

                                if (cmdIndex == 6)
                                {
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = DEC_to_HEX(value);
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                                if (cmdIndex == 3)
                                {
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = strToAscii(value);
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                                if (cmdIndex == 4)
                                {
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = strToAscii(value);
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                                if (cmdIndex == 5)
                                {
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = strToAscii(value);
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                                if (cmdIndex == 8)
                                {
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = DEC_to_HEX(value);
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                                if (cmdIndex == 9)
                                {
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = strToAscii(value);
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                                if (cmdIndex == 10)
                                {
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = strToAscii(value);
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                                if (cmdIndex == 11)
                                {
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = strToAscii(value);
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                            }
                            cmdMessage = DEC_to_2HEX(count.ToString()) + cmdMessage;
                            int messageLen = cmdMessage.Replace(" ", "").Length / 2;//消息体长度
                            string cmdFull = "";
                            int reportId = Convert.ToInt32(cmdReportId, 16);
                            cmdFull = "03 10" + DEC_to_HEX(messageLen.ToString()) + rtuId + DEC_to_HEX(reportId);//消息头
                            cmdFull = cmdFull + cmdMessage;
                            cmdFull = cmdFull + SunCheck(cmdFull);
                            cmdFull = cmdFull.Replace("7E", "7D02").Replace("7D", "7D01");
                            cmdFull = "7E" + cmdFull + "7E";
                            byte[] data = Common.HexStringToByteArray(cmdFull);
                            cmdFull = Common.ByteArrayToHexString(data, 0, data.Length);
                            ShowMessageInWindow("发送指令：" + cmdFull);
                            Send(session.SockeClient, data, session.IP);


                        }

                        //绑卡
                        if ("4".Equals(cmdType))
                        {
                            string jsonStr = dt.Rows[i]["json_str"].ToString();
                            JObject jsonObject = JsonConvert.DeserializeObject<JObject>(jsonStr);
                            JArray cmdData = (JArray)jsonObject["cmdData"];
                            // 
                            string cmdMessage = "";
                            int count = 0;
                            foreach (JObject cmdJson in cmdData)
                            {

                                int cmdIndex = (int)cmdJson["cmdIndex"];
                                string cmdName = (string)cmdJson["cmdName"];
                                string cmdIndexStr = DEC_to_2HEX(cmdIndex.ToString());

                                if (cmdIndex == 40)
                                {
                                    string value = (string)cmdJson["value"];
                                    string valueStr = StringToUtf8Hex(value);
                                    cmdMessage = cmdMessage + valueStr;
                                }
                                if (cmdIndex == 41)
                                {
                                    string value = (string)cmdJson["value"];
                                    string valueStr = StringToUtf8Hex(value);
                                    cmdMessage = cmdMessage + valueStr;
                                }
                                if (cmdIndex == 42)
                                {
                                    string value = (string)cmdJson["value"];
                                    string valueStr = StringToUtf8Hex(value);
                                    cmdMessage = cmdMessage + valueStr;
                                }
                                if (cmdIndex == 43)
                                {
                                    string value = (string)cmdJson["value"];
                                    string valueStr = StringToUtf8Hex(value);
                                    cmdMessage = cmdMessage + valueStr;
                                }
                                if (cmdIndex == 44)
                                {
                                    string value = (string)cmdJson["value"];
                                    string valueStr = StringToUtf8Hex(value);
                                    cmdMessage = cmdMessage + valueStr;
                                }
                            }
                            string cmdFull = "";
                            int reportId = Convert.ToInt32(cmdReportId, 16);
                            cmdFull = "89 00" + "0032" + rtuId + DEC_to_HEX(reportId);//消息头
                            cmdFull = cmdFull + "33 2a 4d 30 36 2c 34 30 2c " + cmdMessage + "23";
                            cmdFull = cmdFull + SunCheck(cmdFull);
                            cmdFull = cmdFull.Replace("7E", "7D02").Replace("7D", "7D01");
                            cmdFull = "7E" + cmdFull + "7E";
                            byte[] data = Common.HexStringToByteArray(cmdFull);
                            cmdFull = Common.ByteArrayToHexString(data, 0, data.Length);
                            ShowMessageInWindow("发送指令：" + cmdFull);
                            Send(session.SockeClient, data, session.IP);


                        }
                        //密码
                        if ("6".Equals(cmdType))
                        {
                            string jsonStr = dt.Rows[i]["json_str"].ToString();
                            JObject jsonObject = JsonConvert.DeserializeObject<JObject>(jsonStr);
                            JArray cmdData = (JArray)jsonObject["cmdData"];
                            // 
                            string cmdMessage = "";
                            int count = 0;
                            foreach (JObject cmdJson in cmdData)
                            {

                                int cmdIndex = (int)cmdJson["cmdIndex"];
                                string cmdName = (string)cmdJson["cmdName"];
                                string cmdIndexStr = DEC_to_2HEX(cmdIndex.ToString());
                                //设置锁控密码
                                if (cmdIndex == 38)
                                {
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = StringToUtf8Hex(value);
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                                //设置司机密码
                                if (cmdIndex == 52)
                                {
                                    count = count + 1;
                                    string value = (string)cmdJson["value"];
                                    string valueStr = StringToUtf8Hex(value);
                                    int len = valueStr.Replace(" ", "").Length / 2;
                                    string lenstr = DEC_to_2HEX(len.ToString());
                                    cmdMessage = cmdMessage + cmdIndexStr + lenstr + valueStr;
                                }
                            }
                            cmdMessage = DEC_to_2HEX(count.ToString()) + cmdMessage;
                            int messageLen = cmdMessage.Replace(" ", "").Length / 2;//消息体长度
                            string cmdFull = "";
                            int reportId = Convert.ToInt32(cmdReportId, 16);
                            cmdFull = "03 10" + DEC_to_HEX(messageLen.ToString()) + rtuId + DEC_to_HEX(reportId);//消息头
                            cmdFull = cmdFull + cmdMessage;
                            cmdFull = cmdFull + SunCheck(cmdFull);
                            cmdFull = cmdFull.Replace("7E", "7D02").Replace("7D", "7D01");
                            cmdFull = "7E" + cmdFull + "7E";
                            byte[] data = Common.HexStringToByteArray(cmdFull);
                            cmdFull = Common.ByteArrayToHexString(data, 0, data.Length);
                            ShowMessageInWindow("发送指令：" + cmdFull);
                            Send(session.SockeClient, data, session.IP);
                        }

                        //设置区域规则
                        if ("7".Equals(cmdType))
                        {
                            string jsonStr = dt.Rows[i]["json_str"].ToString();
                            JObject jsonObject = JsonConvert.DeserializeObject<JObject>(jsonStr);
                            JArray cmdData = (JArray)jsonObject["cmdData"];
                            // 
                            string cmdMessage = "";
                            int count = 0;
                            int index = 0;
                            foreach (JObject cmdJson in cmdData)
                            {

                                string cardId = (string)cmdJson["cardId"];
                                if (cardId == null || cardId == "")
                                {
                                    cardId = "00000000";
                                }
                                double jd = (double)cmdJson["jd"];
                                jd = jd * 1000000;
                                double wd = (double)cmdJson["wd"];
                                wd = wd * 1000000;
                                int banjing = (int)cmdJson["bj"];
                                string zsRule = (string)cmdJson["zsRule"];
                                if (zsRule == null || zsRule == "")
                                {
                                    zsRule = "0000";
                                }
                                cmdMessage = cmdMessage + DEC_to_HEX(index) + cardId + DEC_to_DWORD(jd.ToString()) + DEC_to_DWORD(wd.ToString()) + DEC_to_HEX(banjing) + zsRule;
                                index = index + 1;
                                count = count + 1;

                            }
                            cmdMessage = DEC_to_HEX(count.ToString()) + DEC_to_HEX(count.ToString()) + cmdMessage;
                            int messageLen = cmdMessage.Replace(" ", "").Length / 2;//消息体长度
                            string cmdFull = "";
                            int reportId = Convert.ToInt32(cmdReportId, 16);
                            cmdFull = "03 14" + DEC_to_HEX(messageLen.ToString()) + rtuId + DEC_to_HEX(reportId);//消息头
                            cmdFull = cmdFull + cmdMessage;
                            cmdFull = cmdFull + SunCheck(cmdFull);
                            //cmdFull = cmdFull.Replace("7E", "7D02").Replace("7D", "7D01");
                            cmdFull = "7E" + cmdFull + "7E";
                            byte[] data = Common.HexStringToByteArray(cmdFull);
                            cmdFull = Common.ByteArrayToHexString(data, 0, data.Length);
                            ShowMessageInWindow("发送指令：" + cmdFull);
                            Send(session.SockeClient, data, session.IP);
                        }
                        //查询基础参数
                        if ("8".Equals(cmdType))
                        {
                            string cmdMessage = "10 06 03 04 05 08 09 0A 0B 17 18 19 1A 1B 1C 26  34 ";
                            int messageLen = cmdMessage.Replace(" ", "").Length / 2;//消息体长度
                            string cmdFull = "";
                            int reportId = Convert.ToInt32(cmdReportId, 16);
                            cmdFull = "03 12" + DEC_to_HEX(messageLen.ToString()) + rtuId + DEC_to_HEX(reportId);//消息头
                            cmdFull = cmdFull + cmdMessage;
                            cmdFull = cmdFull + SunCheck(cmdFull);
                            cmdFull = cmdFull.Replace("7E", "7D02").Replace("7D", "7D01");
                            cmdFull = "7E" + cmdFull + "7E";
                            byte[] data = Common.HexStringToByteArray(cmdFull);
                            cmdFull = Common.ByteArrayToHexString(data, 0, data.Length);
                            ShowMessageInWindow("发送指令：" + cmdFull);
                            Send(session.SockeClient, data, session.IP);
                        }
                        //查询附近分锁
                        if ("9".Equals(cmdType))
                        {
                            string cmdMessage = "01 02 01 00";
                            int messageLen = cmdMessage.Replace(" ", "").Length / 2;//消息体长度
                            string cmdFull = "";
                            int reportId = Convert.ToInt32(cmdReportId, 16);
                            cmdFull = "03 20" + DEC_to_HEX(messageLen.ToString()) + rtuId + DEC_to_HEX(reportId);//消息头
                            cmdFull = cmdFull + cmdMessage;
                            cmdFull = cmdFull + SunCheck(cmdFull);
                            cmdFull = cmdFull.Replace("7E", "7D02").Replace("7D", "7D01");
                            cmdFull = "7E" + cmdFull + "7E";
                            byte[] data = Common.HexStringToByteArray(cmdFull);
                            cmdFull = Common.ByteArrayToHexString(data, 0, data.Length);
                            ShowMessageInWindow("发送指令：" + cmdFull);
                            Send(session.SockeClient, data, session.IP);
                        }
                        //查询绑卡信息
                        if ("10".Equals(cmdType))
                        {
                            string cmdMessage = "33 2a 4d 30 37 2c 30 30 2c 23 ";
                            int messageLen = cmdMessage.Replace(" ", "").Length / 2;//消息体长度
                            string cmdFull = "";
                            int reportId = Convert.ToInt32(cmdReportId, 16);
                            cmdFull = "89 00" + DEC_to_HEX(messageLen.ToString()) + rtuId + DEC_to_HEX(reportId);//消息头
                            cmdFull = cmdFull + cmdMessage;
                            cmdFull = cmdFull + SunCheck(cmdFull);
                            cmdFull = cmdFull.Replace("7E", "7D02").Replace("7D", "7D01");
                            cmdFull = "7E" + cmdFull + "7E";
                            byte[] data = Common.HexStringToByteArray(cmdFull);
                            cmdFull = Common.ByteArrayToHexString(data, 0, data.Length);
                            ShowMessageInWindow("发送获得绑卡信息指令：" + cmdFull);
                            Send(session.SockeClient, data, session.IP);
                        }
                    }
                    catch (Exception ex)
                    {
                        ShowMessageInWindow("发送控制指令异常：" + ex.Message);
                    }
                }

            }
            catch (Exception ex)
            {
                ShowMessageInWindow("发送控制指令异常：" + ex.Message);
            }
        }

        public string StringToUtf8Hex(string text)
        {
            // 使用UTF-8编码获取字符串的字节数组
            byte[] utf8Bytes = Encoding.UTF8.GetBytes(text);

            // 将字节数组转换为十六进制字符串
            StringBuilder hexBuilder = new StringBuilder();
            for (int i = 0; i < utf8Bytes.Length; i++)
            {
                hexBuilder.Append(utf8Bytes[i].ToString("X2"));
            }

            // 返回十六进制字符串
            return hexBuilder.ToString();
        }

        public string strToAscii(string text)
        {
            StringBuilder sb = new StringBuilder();

            foreach (char c in text)
            {
                // 将字符转换为其ASCII码的16进制表示形式
                sb.Append(Convert.ToString((int)c, 16) + " ");
            }
            string result = sb.ToString();
            return result;

        }

        /// <summary>
        /// 数字字符串转为ascii 码
        /// </summary>
        /// <param name="no"></param>
        /// <returns></returns>
        public string decToAscii(string no)
        {
            string result = "";
            for (int i = 0; i < no.Length; i++)
            {
                result = result + "3" + no[i];
            }
            return result;
        }

        public void Test()
        {
            string data = "7E 02 00 00 57 04 20 75 60 98 86 00 CF 00 00 00 00 00 00 00 02 02 67 7D 01 90 06 53 D8 E8 00 00 00 00 00 7D 02 25 05 09 10 58 32 01 04 00 00 00 00 36 0B 01 01 3F C0 00 00 02 41 C4 00 00 33 26 2A 4D 30 30 2C 32 39 2C 31 30 34 31 32 30 30 30 30 30 30 30 30 30 30 26 33 30 30 30 30 30 30 30 30 30 30 30 26 23 58 7E";
            data = data.Replace(" ", "");
            string cellData = data.Substring(82, data.Length - 82 - 4);
            ModelDevice device = new ModelDevice();
            device.DeviceId = "1";
            device.DeviceName = "1";
            CellDataHandle(cellData, device);
        }


        public ArgModel getArg(string str, ArgModel argModel)
        {
            if (str.Length == 0)
            {
                return argModel;
            }
            string cmdId = str.Substring(0, 2);
            string lenStr = str.Substring(2, 2);
            int len = Convert.ToInt32(lenStr, 16);
            string argCellStr = str.Substring(4, 2 * len);
            ArgCellHandle(cmdId, argCellStr, argModel);
            int lenth = 4 + 2 * len;
            str = str.Substring(lenth, str.Length - lenth);
            return getArg(str, argModel);
        }

        public void ArgCellHandle(string cmdId, string str, ArgModel argModel)
        {
            string resultData = str;
            switch (cmdId)
            {
                case "01":
                    {
                        //设备编号
                        string deviceCode = str;
                        argModel.deviceCode = deviceCode;
                        break;
                    }
                case "06":
                    {
                        //定时汇报间隔
                        long sbjg = Convert.ToUInt32(resultData, 16);
                        argModel.sbjg = sbjg;
                        break;
                    }
                case "03":
                    {
                        //主服务器ip
                        string ip = ConvertAsciiToString(resultData);
                        argModel.mainIp = ip;
                        break;
                    }
                case "04":
                    {
                        //备用服务器ip
                        string ip = ConvertAsciiToString(resultData);
                        argModel.bfIp = ip;
                        break;
                    }
                case "05":
                    {
                        //端口
                        string port = ConvertAsciiToString(resultData);
                        argModel.port = port;
                        break;
                    }
                case "08":
                    {
                        //终端心跳间隔
                        long hearBeat = Convert.ToUInt32(resultData, 16);
                        argModel.heartBeat = hearBeat;
                        break;
                    }
                case "09":
                    {
                        //apn 名称 sim卡1
                        string apnName = ConvertAsciiToString(resultData);
                        argModel.apnName = apnName;
                        break;
                    }
                case "0A":
                    {
                        //apn 用户名 sim卡1
                        string apnUser = ConvertAsciiToString(resultData);
                        argModel.apnUser = apnUser;
                        break;
                    }
                case "0B":
                    {
                        //apn 密码 sim卡1
                        string apnPassword = ConvertAsciiToString(resultData);
                        argModel.apnPassword = apnPassword;
                        break;
                    }
                case "17":
                    {
                        //lock1
                        string lock1 = ConvertAsciiToString(resultData);
                        argModel.lockNum1 = lock1;
                        break;
                    }
                case "18":
                    {
                        //lock2
                        string lock2 = ConvertAsciiToString(resultData);
                        argModel.lockNum2 = lock2;
                        break;
                    }
                case "19":
                    {
                        //lock3
                        string lock3 = ConvertAsciiToString(resultData);
                        argModel.lockNum3 = lock3;
                        break;
                    }
                case "1A":
                    {
                        //lock4
                        string lock4 = ConvertAsciiToString(resultData);
                        argModel.lockNum4 = lock4;
                        break;
                    }
                case "1B":
                    {
                        //lock5
                        string lock5 = ConvertAsciiToString(resultData);
                        argModel.lockNum5 = lock5;
                        break;
                    }
                case "1C":
                    {
                        //lock6
                        string lock6 = ConvertAsciiToString(resultData);
                        argModel.lockNum6 = lock6;
                        break;
                    }
                case "26":
                    {
                        //锁控密码
                        string skPassword = ConvertAsciiToString(resultData);
                        argModel.skPassword = skPassword;
                        break;
                    }
                case "34":
                    {
                        //司机密码
                        string driverPassword = ConvertAsciiToString(resultData);
                        argModel.driverPassword = driverPassword;
                        break;
                    }
                defalt: break;
            }
        }

        public string ConvertAsciiToString(string asciiValues)
        {
            // 将字符串分割成数值数组
            //  byte[] asciiNumbers = Encoding.Default.GetBytes(asciiValues);
            byte[] asciiNumbers = Common.HexStringToByteArray(asciiValues);
            string result = System.Text.Encoding.ASCII.GetString(asciiNumbers);
            return result;
        }


        public class ArgModel
        {
            public string deviceCode { get; set; }
            public string deviceId { get; set; }
            public string deviceName { get; set; }
            public long sbjg { get; set; }
            public string mainIp { get; set; }
            public string bfIp { get; set; }
            public string port { get; set; }
            public long heartBeat { get; set; }
            public string apnName { get; set; }
            public string apnUser { get; set; }
            public string apnPassword { get; set; }
            public string skPassword { get; set; }
            public string driverPassword { get; set; }
            public string lockNum1 { get; set; }
            public string lockNum2 { get; set; }
            public string lockNum3 { get; set; }
            public string lockNum4 { get; set; }
            public string lockNum5 { get; set; }
            public string lockNum6 { get; set; }

        }



        public string SunCheck(string cmd)
        {
            string verify = "";
            byte[] uBuff = Common.HexStringToByteArray(cmd);
            int uBuffLen = uBuff.Length;
            ushort crc = 0X0000;
            for (int j = 0; j < uBuffLen; j++)
            {
                crc ^= uBuff[j];
            }
            verify = crc.ToString("X2");
            return verify;
        }

        /// <summary>
        /// 16进制的字符串相加，得到16进制字符串
        /// </summary>
        /// <param name="s1">16进制字符串s1</param>
        /// <param name="s2">16进制字符串s2</param>
        /// <returns>16进制字符串</returns>
        public string str16Sum(string s1, string s2)
        {
            string result = "";
            s1 = s1.Replace(" ", "");
            s2 = s2.Replace(" ", "");
            long l1 = Convert.ToInt64(s1, 16);
            long l2 = Convert.ToInt64(s2, 16);
            long l = l1 + l2;
            result = l.ToString("X");
            return result;
        }

        /// <summary>
        /// 字符串十进制转为 int类型十进制
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public int StringToDec(string s)
        {
            int n = 0;
            for (int i = 0; i < s.Length; i++)
            {
                n = 10 * n + (s[i] - '0');
            }
            return n;

        }


        #region 启动WebSocket服务
        /// <summary>
        /// 启动WebSocket服务
        /// </summary>
        private void listenerInit()
        {
            string portStr = portTextbox.Text.Replace(" ", "");
            if (portStr.Length == 0 || !IsInt(portStr))
            {
                MessageBox.Show("非整数");
                return;
            }
            port = int.Parse(portStr);
            if (port < 0 || port > 65535)
            {
                MessageBox.Show("超出端口的使用范围，可用范围为：0-65535");
                return;
            }
            Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            Socket.Bind(new IPEndPoint(IPAddress.Any, port));
            Socket.Listen(0);
            Socket.BeginAccept(new AsyncCallback(Accept), Socket);
            ShowMessageInWindow(port + "端口 服务已启动");
            switchButton.Text = "停止监听";
        }
        #endregion

        public bool IsInt(string value)
        {
            return Regex.IsMatch(value, @"^[+-]?\d*$");
        }

        #region 处理客户端连接请求
        /// <summary>
        /// 处理客户端连接请求
        /// </summary>
        /// <param name="result"></param>
        private void Accept(IAsyncResult socket)
        {
            try
            {
                // 还原传入的原始套接字
                Socket SockeServer = (Socket)socket.AsyncState;
                // 在原始套接字上调用EndAccept方法，返回新的套接字
                Socket SockeClient = SockeServer.EndAccept(socket);
                byte[] buffer = new byte[4096];
                //接收客户端的数据
                SockeClient.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(Recieve), SockeClient);
                //保存登录的客户端
                Session session = new Session();
                session.SockeClient = SockeClient;
                IPEndPoint ipEndPoint = (IPEndPoint)SockeClient.RemoteEndPoint;
                string AdrFamily = ipEndPoint.AddressFamily.ToString();//地址类型
                string IpStr = ipEndPoint.Address.ToString();//IP地址点分表达方式
                string IpPort = ipEndPoint.Port.ToString();//IP地址端口  
                session.IP = IpStr;
                session.buffer = buffer;
                
                // 初始化心跳相关属性
                session.LastRecDataTime = DateTime.Now;
                session.LastHeartBeatTime = DateTime.Now;
                session.HeartBeatFailCount = 0;
                session.NeedHeartBeat = true;
                lock (locker)
                {
                    List<IntPtr> test = new List<IntPtr>(serverSessionPool.Keys);
                    for (int i = serverSessionPool.Count - 1; i >= 0; i--)
                    {
                        if (session.IP.Equals(serverSessionPool[test[i]].IP))
                        {
                            removeSocketClient(serverSessionPool[test[i]].SockeClient.Handle);
                        }
                    }
                    serverSessionPool.Add(SockeClient.Handle, session);

                    Invoke(new Action(delegate
                    {
                        TreeNode treeNode = new TreeNode();
                        treeNode.Tag = SockeClient.Handle;
                        treeNode.Text = IpStr;
                        socketClinetTree.Nodes.Add(treeNode);
                        comboBox1.Items.Add(SockeClient.Handle);
                    }));

                }
                //准备接受下一个客户端
                SockeServer.BeginAccept(new AsyncCallback(Accept), SockeServer);
                ShowMessageInWindow(string.Format("Client {0} connected", SockeClient.RemoteEndPoint));
            }
            catch (Exception ex)
            {
                ShowMessageInWindow("Error : " + ex.ToString());
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message);//将出错信息写入错误日志                    
            }
        }
        /// <summary>
        /// 处理接受的数据
        /// </summary>
        /// <param name="socket"></param>
        private void Recieve(IAsyncResult socket)
        {
            string IP = "";
            IntPtr intPtr = new IntPtr();
            try
            {
                Socket SockeClient = (Socket)socket.AsyncState;
                intPtr = SockeClient.Handle;
                if (SockeClient == null || !SockeClient.Connected)
                {
                    ShowMessageInWindow(MethodBase.GetCurrentMethod().Name + " 客户端不存在或者已断开连接");
                    SafeClose(SockeClient);
                    return;
                }
                int length = SockeClient.EndReceive(socket);
                if (length == 0)
                {
                    return;
                }

                IPEndPoint ipEndPoint = (IPEndPoint)SockeClient.RemoteEndPoint;
                string AdrFamily = ipEndPoint.AddressFamily.ToString();//地址类型
                string IpStr = ipEndPoint.Address.ToString();//IP地址点分表达方式
                string IpPort = ipEndPoint.Port.ToString();//IP地址端口 
                IP = IpStr;

                byte[] buffer = null;
                bool sessionExists = false;

                lock (locker)
                {
                    if (serverSessionPool.ContainsKey(SockeClient.Handle))
                    {
                        buffer = serverSessionPool[SockeClient.Handle].buffer;
                        serverSessionPool[intPtr].LastRecDataTime = DateTime.Now;//更新上一条数据时间
                        sessionExists = true;
                    }
                }

                if (!sessionExists)
                {
                    ShowMessageInWindow("会话已不存在，关闭连接: " + IP);
                    SafeClose(SockeClient);
                    return;
                }
                SockeClient.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(Recieve), SockeClient);
                string msg = Common.ByteArrayToHexString(buffer, 0, length);
                ShowMessageInWindow("ip：" + IP + " 返回数据：" + msg);
                msg = msg.Replace(" ", "");
                int msgLength = msg.Length;
                if (msgLength > 8)
                {
                    MyThreadModel mod = new MyThreadModel();
                    mod.socketClient = SockeClient;
                    mod.msg = msg;
                    Thread thread = new Thread(new ParameterizedThreadStart(DataThread));
                    thread.Start(mod);
                }

            }
            catch (SocketException ex)
            {
                ShowMessageInWindow(string.Format(MethodBase.GetCurrentMethod().Name + " 客户端 {0} 发生socket异常 {1}", IP, ex.Message));
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message + "\r\n");//将出错信息写入错误日志 
                removeSocketClient(intPtr);
            }
            catch (Exception ex)
            {
                ShowMessageInWindow(string.Format(MethodBase.GetCurrentMethod().Name + " 客户端 {0} 发生一般异常 {1}", IP, ex.Message));
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message + "\r\n");//将出错信息写入错误日志               
            }
        }
        #endregion

        public void DataThread(object obj)
        {
            try
            {
                MyThreadModel mod = obj as MyThreadModel;
                string msg = mod.msg;
                Socket SockeClient = mod.socketClient;
                List<string> dataList = EffectData(msg);

                for (int i = 0; i < dataList.Count(); i++)
                {
                    DataHandle(dataList[i], SockeClient);
                }
            }
            catch (Exception ex)
            {
                ShowMessageInWindow(string.Format(MethodBase.GetCurrentMethod().Name, ex.Message));
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message + "\r\n");//将出错信息写入错误日志             
            }

        }

        public List<string> EffectData(string data)
        {
            List<string> result = new List<string>();
            for (int i = 0; i < data.Length; i++)
            {
                data = data.Substring(i);
                if (data.IndexOf("7E") < 0)
                {
                    return result;
                }
                int start = data.IndexOf("7E");

                int endTemp = data.Substring(start + 2).IndexOf("7E");
                if (endTemp > 0)
                {
                    string tempStr = data.Substring(start, endTemp - start + 2 + 2);
                    //转义还原 0x7e<——>0x7d 后紧跟一个 0x02； 0x7d<——>0x7d 后紧跟一个 0x01。
                    tempStr = tempStr.Replace("7D02", "7E");
                    tempStr = tempStr.Replace("7D01", "7D");
                    string str = tempStr.Substring(2, tempStr.Length - 4);//截取去除前后"7E"部分
                    string suncheck = SunCheck(str);
                    if ("00".Equals(suncheck))
                    {
                        result.Add(tempStr);
                    }
                    i = endTemp + 4 - 1;
                }
                else
                {
                    return result;
                }
            }
            return result;
        }

        public string from16ToBinaryString(string hexString)
        {
            StringBuilder binaryStringBuilder = new StringBuilder();

            foreach (char hexChar in hexString)
            {
                // 将16进制字符转换为数值
                int value = Convert.ToInt32(hexChar.ToString(), 16);
                // 将数值转换为4位二进制，并追加到StringBuilder中
                binaryStringBuilder.Append(Convert.ToString(value, 2).PadLeft(4, '0'));
            }

            string binaryString = binaryStringBuilder.ToString();
            return binaryString;
        }

        public void DataHandle(string data, Socket sockeClient)
        {
            if (string.IsNullOrEmpty(data) || sockeClient == null)
            {
                ShowMessageInWindow("DataHandle: 无效参数 - data或sockeClient为空");
                return;
            }

            string deviceId = "";
            string deviceName = "";
            try
            {
                int Length = data.Length;

                // 验证数据长度的基本要求
                if (Length < 8)
                {
                    ShowMessageInWindow("DataHandle: 数据长度不足，舍弃数据: " + data);
                    return;
                }
                string messageId = data.Substring(2, 4); //消息id

                if ("0200".Equals(messageId))
                {
                    Common.WriteErrorLog("0200:" + data);
                    ModelDevice mod = new ModelDevice();
                    string lengthStr = data.Substring(6, 4);
                    int length = Convert.ToInt32(lengthStr, 16);//消息体长度，不包含校验码及帧尾标识符以及消息头的所有内容
                    string teminalSeq = data.Substring(10, 12); //终端序列号
                    string seq = data.Substring(22, 4);//流水号  

                    //发送确认消息
                    string cmd = "80 01" + "00 05" + teminalSeq + getSeq() + seq + "02 00" + " 00";
                    string suncheck = SunCheck(cmd);
                    cmd = cmd + suncheck;
                    cmd = zhuanYi(cmd);
                    //cmd = cmd.Replace("7E", "7D02").Replace("7D", "7D01");
                    cmd = "7E" + cmd + "7E";
                    byte[] responseDate = Common.HexStringToByteArray(cmd);
                    Delay(1000);
                    ShowMessageInWindow(deviceName + " 回复应答" + cmd);

                    Send(sockeClient, responseDate);
                    Common.WriteErrorLog("应答0200:" + cmd);
                    ////发送0320 维护指令 获得电量信号等
                    // cmd = "03 20" + "00 04" + teminalSeq  + getSeq()  + "01 02 01 00";
                    // suncheck = SunCheck(cmd);
                    //cmd = cmd + suncheck;
                    //cmd = cmd.Replace("7E", "7D02").Replace("7D", "7D01");
                    //cmd = "7E" + cmd + "7E";
                    //responseDate = Common.HexStringToByteArray(cmd);
                    //ShowMessageInWindow(deviceName + " 回复应答" + cmd);
                    //Send(sockeClient, responseDate);

                    //serverSessionPool[sockeClient.Handle].RtuId = teminalSeq;
                    if (serverSessionPool.ContainsKey(sockeClient.Handle) && serverSessionPool[sockeClient.Handle] != null)
                    {
                        serverSessionPool[sockeClient.Handle].RtuId = teminalSeq;
                    }
                    else
                    {
                        Common.WriteErrorLog("serverSessionPool 中未找到对应的 socketClient.Handle：" + sockeClient.Handle.ToString());
                        return; // 或者 throw new Exception("找不到会话信息");
                    }

                    DataRow[] drow = dtDevice.Select("rtu_id='" + teminalSeq + "'");
                    if (dtDevice == null)
                    {
                        Common.WriteErrorLog("dtDevice 为 null，无法查找设备");
                        return;
                    }
                    if (drow.Count() == 1)
                    {
                        deviceId = drow[0]["node_id"].ToString();
                        serverSessionPool[sockeClient.Handle].DeviceId = deviceId;
                        deviceName = drow[0]["node_name"].ToString();
                        serverSessionPool[sockeClient.Handle].DeviceName = deviceName;
                    }
                    if (drow.Count() == 0)
                    {
                        ShowMessageInWindow("不包含拥有 RTUid为:" + teminalSeq + "的设备");
                        Common.WriteErrorLog("不包含拥有 RTUid为:" + teminalSeq + "的设备");
                    }
                    if (drow.Count() > 1)
                    {
                        ShowMessageInWindow("多个设备拥有 RTU_ID:" + teminalSeq);
                        Common.WriteErrorLog("多个设备拥有 RTU_ID:" + teminalSeq);
                    }

                    if (data.Length < 86)  // 最小长度要求
                    {
                        Common.WriteErrorLog("数据格式异常，长度不足：" + data.Length + "，内容：" + data);
                        return;
                    }

                    mod.fullData = data;
                    mod.rtuId = teminalSeq;
                    mod.DeviceId = deviceId;
                    mod.DeviceName = deviceName;

                    string warnFlag = data.Substring(26, 8);// 报警标志位

                    string statusFlag = data.Substring(34, 8);//状态位定义
                    string statusStr = from16ToBinaryString(statusFlag);
                    string isLocatedStr = statusStr.Substring(30, 1);
                    string isLocated = isLocatedStr == "1" ? "定位" : "未定位";
                    mod.isLocated = isLocated;
                    string latStr = data.Substring(42, 8);
                    double lat = Convert.ToInt64(latStr, 16) / 1000000d; //纬度
                    mod.LAT = lat;
                    string lntStr = data.Substring(50, 8);
                    double lnt = Convert.ToInt64(lntStr, 16) / 1000000d; //经度
                    mod.LNG = lnt;
                    string altStr = data.Substring(58, 4);
                    int alt = Convert.ToInt32(altStr, 16);//海拔高度
                    mod.ALT = alt;

                    string vStr = data.Substring(62, 4);
                    double v = Convert.ToInt32(vStr, 16);  //速度
                    mod.V = v;
                    string dirStr = data.Substring(66, 4);
                    int dir = Convert.ToInt32(dirStr, 16); //方向
                    mod.Direction = dir;
                    string timeStr = data.Substring(70, 12); //时间
                    try
                    {
                        string year = "20" + timeStr.Substring(0, 2);
                        string month = timeStr.Substring(2, 2);
                        string day = timeStr.Substring(4, 2);
                        string hh = timeStr.Substring(6, 2);
                        string mi = timeStr.Substring(8, 2);
                        string ss = timeStr.Substring(10, 2);
                        DateTime stime = Convert.ToDateTime(year + "-" + month + "-" + day + " " + hh + ":" + mi + ":" + ss);
                    }
                    catch (Exception ex)
                    {

                    }
                    mod.cmdType = 0;
                    AddRunCommonData(mod);
                    string cellData = data.Substring(82, data.Length - 82 - 4);
                    CellDataHandle(cellData, mod);
                }
                if ("0210".Equals(messageId))
                {
                    Common.WriteErrorLog("0210:" + data);
                    ModelDevice mod = new ModelDevice();
                    string lengthStr = data.Substring(6, 4);
                    int length = Convert.ToInt32(lengthStr, 16);//消息体长度，不包含校验码及帧尾标识符以及消息头的所有内容
                    string teminalSeq = data.Substring(10, 12); //终端序列号
                    string seq = data.Substring(22, 4);//流水号  

                    //发送确认消息
                    string cmd = "80 01" + "00 05" + teminalSeq + getSeq() + seq + "02 10" + " 00";
                    string suncheck = SunCheck(cmd);
                    cmd = cmd + suncheck;
                    cmd = zhuanYi(cmd);
                    //cmd = cmd.Replace("7E", "7D02").Replace("7D", "7D01");
                    cmd = "7E" + cmd + "7E";
                    byte[] responseDate = Common.HexStringToByteArray(cmd);
                    Delay(1000);
                    ShowMessageInWindow(deviceName + " 回复应答" + cmd);
                    Send(sockeClient, responseDate);
                    Common.WriteErrorLog("应答0210:" + cmd);
                }
                if ("0311".Equals(messageId))
                {
                    string lengthStr = data.Substring(6, 4);
                    int length = Convert.ToInt32(lengthStr, 16);//消息体长度，不包含校验码及帧尾标识符以及消息头的所有内容
                    string teminalSeq = data.Substring(10, 12); //终端序列号
                    string seq = data.Substring(22, 4);//消息流水号 
                    string cmdReportId = data.Substring(26, 4);//对应终端消息的流水号 
                    int cmdId = Convert.ToInt32(cmdReportId, 16);
                    string propCountStr = data.Substring(30, 2);//参数个数
                    int propCount = Convert.ToInt32(propCountStr, 16);//这里一次性只设置一种参数，一般都是1
                    string propId = data.Substring(32, 2);
                    string isSuccess = data.Substring(34, 2) == "00" ? "成功" : "失败";
                    Common.ExecuteNonQuery("update sys_control set status='" + isSuccess + "',mark=1 where CMD_REPORT_ID='" + cmdId + "'");
                }

                if ("0313".Equals(messageId))
                {                                                                           //
                    data = data.Replace(" ", "");
                    string lengthStr = data.Substring(6, 4);
                    int length = Convert.ToInt32(lengthStr, 16);//消息体长度，不包含校验码及帧尾标识符以及消息头的所有内容
                    string teminalSeq = data.Substring(10, 12); //终端序列号
                    string seq = data.Substring(22, 4);//消息流水号 
                    string cmdReportId = data.Substring(26, 4);//对应终端消息的流水号 
                    int cmdId = Convert.ToInt32(cmdReportId, 16);
                    string countStr = data.Substring(30, 2);//对应查询参数个数
                    int count = Convert.ToInt32(countStr, 16);
                    string result = data.Substring(32, data.Length - 32 - 4);
                    ArgModel argModel = new ArgModel();
                    DataRow[] drow = dtDevice.Select("rtu_id='" + teminalSeq + "'");
                    if (drow.Count() == 1)
                    {
                        deviceId = drow[0]["node_id"].ToString();
                        deviceName = drow[0]["node_name"].ToString();
                        argModel.deviceId = deviceId;
                        argModel.deviceName = deviceName;
                    }
                    if (drow.Count() == 0)
                    {
                        ShowMessageInWindow("不包含拥有 RTUid为:" + teminalSeq + "的设备");
                        Common.WriteErrorLog("不包含拥有 RTUid为:" + teminalSeq + "的设备");
                    }
                    if (drow.Count() > 1)
                    {
                        ShowMessageInWindow("多个设备拥有 RTU_ID:" + teminalSeq);
                        Common.WriteErrorLog("多个设备拥有 RTU_ID:" + teminalSeq);
                    }
                    argModel = getArg(result, argModel);
                    AddArgData(argModel);
                    if (cmdReportId != "1FFF")
                    {
                        Common.ExecuteNonQuery("update sys_control set status='" + "成功" + "',mark=1 where CMD_REPORT_ID='" + cmdId + "'");
                    }

                }

                if ("0315".Equals(messageId))
                {                                                                           //
                    data = data.Replace(" ", "");
                    string lengthStr = data.Substring(6, 4);
                    int length = Convert.ToInt32(lengthStr, 16);//消息体长度，不包含校验码及帧尾标识符以及消息头的所有内容
                    string teminalSeq = data.Substring(10, 12); //终端序列号
                    string seq = data.Substring(22, 4);//消息流水号 
                    string cmdReportId = data.Substring(26, 4);//对应终端消息的流水号 
                    int cmdId = Convert.ToInt32(cmdReportId, 16);
                    Common.ExecuteNonQuery("update sys_control set status='" + "成功" + "',mark=1 where CMD_REPORT_ID='" + cmdId + "'");

                }

                if ("0321".Equals(messageId))
                {                                                                           //
                    data = data.Replace(" ", "");
                    string lengthStr = data.Substring(6, 4);
                    int length = Convert.ToInt32(lengthStr, 16);//消息体长度，不包含校验码及帧尾标识符以及消息头的所有内容
                    string teminalSeq = data.Substring(10, 12); //终端序列号
                    string seq = data.Substring(22, 4);//消息流水号 
                    string cmdReportId = data.Substring(26, 4);//对应终端消息的流水号 
                    int cmdId = Convert.ToInt32(cmdReportId, 16);
                    string countStr = data.Substring(30, 2);//对应查询参数个数
                    int count = Convert.ToInt32(countStr, 16);
                    string cmdTypeStr = data.Substring(32, 2);
                    string lenStr = data.Substring(34, 2);
                    int len = Convert.ToInt32(lenStr, 16);
                    int lockNum = len / 9;

                    DataRow[] drow = dtDevice.Select("rtu_id='" + teminalSeq + "'");
                    if (drow.Count() == 1)
                    {
                        deviceId = drow[0]["node_id"].ToString();
                        deviceName = drow[0]["node_name"].ToString();
                    }
                    if (drow.Count() == 0)
                    {
                        ShowMessageInWindow("不包含拥有 RTUid为:" + teminalSeq + "的设备");
                        Common.WriteErrorLog("不包含拥有 RTUid为:" + teminalSeq + "的设备");
                    }
                    if (drow.Count() > 1)
                    {
                        ShowMessageInWindow("多个设备拥有 RTU_ID:" + teminalSeq);
                        Common.WriteErrorLog("多个设备拥有 RTU_ID:" + teminalSeq);
                    }
                    string lockStr = data.Substring(36, len * 2);
                    List<LockModel> lockModels = new List<LockModel>();
                    for (int i = 0; i < lockNum; i++)
                    {
                        string str = lockStr.Substring(18 * i, 18);
                        string lockAscii = str.Substring(0, 12);
                        string lock1Num = ConvertAsciiToString(lockAscii);
                        string statusStr = str.Substring(12, 2);
                        string status = statusStr == "30" ? "开" : "关";
                        //电量
                        string dlStr = str.Substring(14, 2);
                        long dlInt = Convert.ToInt32(dlStr, 16);
                        double dl = 3.3d * (double)dlInt / 255d;
                        //信号
                        string signalStr = str.Substring(16, 2);
                        long signalInt = Convert.ToInt32(signalStr, 16);
                        double signal = 100d * (double)signalInt / 255d;
                        LockModel lockModel = new LockModel();
                        lockModel.lockNum = lock1Num;
                        lockModel.status = status;
                        lockModel.dl = dl;
                        lockModel.signal = signal;
                        lockModels.Add(lockModel);
                    }
                    LockModel addModel = new LockModel();
                    addModel.deviceId = deviceId;
                    addModel.deviceName = deviceName;
                    addModel.cmdData = data;
                    string lockJson = JsonConvert.SerializeObject(lockModels);
                    addModel.lockJson = lockJson;
                    AddSearchLockData(addModel);
                    if (cmdReportId != "2FFF")
                    {
                        Common.ExecuteNonQuery("update sys_control set status='" + "成功" + "',mark=1 where CMD_REPORT_ID='" + cmdId + "'");
                    }
                }
            }
            catch (Exception ex)
            {
                ShowMessageInWindow(string.Format(MethodBase.GetCurrentMethod().Name + " 客户端 {0} 发生一般异常 {1}", serverSessionPool[sockeClient.Handle].DeviceName, ex.Message));
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message + "\r\n");//将出错信息写入错误日志               
            }
        }

        public class LockModel
        {
            public string deviceId { get; set; }
            public string deviceName { get; set; }
            public string lockNum { get; set; }
            public string status { get; set; }
            public double dl { get; set; }
            public double signal { get; set; }
            public string cmdData { get; set; }
            public string lockJson { get; set; }
        }

        public ModelDevice CellDataHandle(string data, ModelDevice mod)
        {

            try
            {
                if (data.Length == 0)
                {
                    return mod;
                }
                string id = data.Substring(0, 2);
                string lengthStr = data.Substring(2, 2);
                int dataLength = Convert.ToInt32(lengthStr, 16);
                string resultData = data.Substring(4, dataLength * 2);
                CellDataPase(resultData, id, mod);
                data = data.Substring(4 + 2 * dataLength);
                return CellDataHandle(data, mod);
            }
            catch (Exception ex)
            {
                ShowMessageInWindow(MethodBase.GetCurrentMethod().Name + ex.Message);
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message + "\r\n");//将出错信息写入错误日志          
                return mod;
            }
        }

        /// <summary>
        /// rtu 扩展单元解析
        /// </summary>
        /// <param name="cellData"></param>
        /// <param name="Id"></param>
        /// <param name="mod"></param>
        /// <returns></returns>
        public ModelDevice CellDataPase(string cellData, string Id, ModelDevice mod)
        {
            string resultData = cellData;
            switch (Id)
            {
                case "01":
                    {
                        //里程
                        long licheng = Convert.ToInt64(cellData, 16);
                        break;
                    }
                case "02":
                    {
                        //油量
                        int oilQuality = Convert.ToInt32(cellData, 16);
                        break;
                    }
                case "33":
                    {
                        string result = Common.HexToStr(cellData);
                        //*M00,29,103920080021806&025000000000&#
                        // *M06,01,1# 绑卡指令响应
                        //*M07,40,1234567811111111222222223333333344444444#  M07获得绑卡信息
                        string cmdType = result.Substring(1, 3);
                        if (cmdType == "M07")
                        {
                            string cardId1 = result.Substring(8, 8);
                            string cardId2 = result.Substring(16, 8);
                            string cardId3 = result.Substring(24, 8);
                            string cardId4 = result.Substring(32, 8);
                            string cardId5 = result.Substring(40, 8);

                            string sqlText = string.Format("insert into card_id_log (DEVICE_ID,DEVICE_NAME,card_id1,card_id2,card_id3,card_id4,card_id5,stime) "
                                               + " values ('{0}','{1}','{2}','{3}','{4}','{5}','{6}',TO_DATE('{7}','yyyy-mm-dd hh24:mi:ss'))",
                                                   mod.DeviceId, mod.DeviceName, cardId1, cardId2, cardId3, cardId4, cardId5, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                            int intResult1 = Common.ExecuteNonQuery(sqlText);

                            if (intResult1 >= 1)
                            {
                                ShowMessageInWindow("插入绑卡信息成功");
                            }
                        }
                        if (cmdType == "M06")
                        {
                            string isSuccessStr = result.Substring(8, 1);
                            string isSuccess = isSuccessStr == "1" ? "成功" : "失败";
                            Common.ExecuteNonQuery("update sys_control set status='" + isSuccess + "',mark=1 where device_id='" + mod.DeviceId + "' and cmd_type='4'");
                        }
                        if (cmdType == "M00")
                        {
                            string termStatus = result.Substring(8, 7);//终端状态
                            int U = Convert.ToInt32(termStatus.Substring(2, 3));
                            string isRemove = termStatus.Substring(5, 1);//防拆开关状态: 0----正常 1----被拆触发
                            if (isRemove == "1")
                            {
                                alarmData alarmData = new alarmData();
                                alarmData.name = mod.DeviceName;
                                alarmData.deviceId = mod.DeviceId;
                                alarmData.type = "被拆报警";
                                AddAlarmData(alarmData);
                            }
                            string reportReason = termStatus.Substring(6, 1);//上报原因                    
                            int start = result.IndexOf("&");
                            int end = result.IndexOf("&", start + 1);

                            string handleId = result.Substring(15, start - 16 + 1);//操作id
                                                                                   //if (reportReason != "0")
                                                                                   //{
                                                                                   //    if (reportTypeDic.ContainsKey(reportReason))
                                                                                   //    {
                            reportData reportDataMod = new reportData();
                            reportDataMod.deviceId = mod.DeviceId;
                            reportDataMod.deviceName = mod.DeviceName;
                            reportDataMod.reportType = reportReason;
                            reportDataMod.reportTypeName = reportTypeDic[reportReason];
                            reportDataMod.handleId = handleId;
                            reportDataMod.cmd = termStatus;
                            reportDataMod.fullCmd = result;
                            AddReportData(reportDataMod);

                            //    }
                            //}

                            string lockStatus = result.Substring(start + 1, 12);
                            string businessId = result.Substring(end + 1, result.Length - end - 1 - 1);


                            lockStatus lockModel = new lockStatus();
                            lockModel.deviceId = mod.DeviceId;
                            lockModel.deviceName = mod.DeviceName;
                            lockModel.rtuId = mod.rtuId;
                            lockModel.data = result;
                            lockModel.fullData = cellData;
                            //如果是施封状态下，则在原值基础上加10，即施封状态下大于40
                            byte[] a = Encoding.Default.GetBytes(lockStatus);

                            lockModel.lock1 = lockStatus.Substring(0, 1);
                            lockModel.lock2 = lockStatus.Substring(1, 1);
                            lockModel.lock3 = lockStatus.Substring(2, 1);
                            lockModel.lock4 = lockStatus.Substring(3, 1);
                            lockModel.lock5 = lockStatus.Substring(4, 1);
                            lockModel.lock6 = lockStatus.Substring(5, 1);
                            lockModel.lock7 = lockStatus.Substring(6, 1);
                            lockModel.lock8 = lockStatus.Substring(7, 1);
                            lockModel.lock9 = lockStatus.Substring(8, 1);
                            lockModel.lock10 = lockStatus.Substring(9, 1);
                            lockModel.lock11 = lockStatus.Substring(10, 1);
                            lockModel.lock12 = lockStatus.Substring(11, 1);
                            ShowMessageInWindow(mod.DeviceName + " 主锁 " + lockModel.mainLock
                                + " 锁1 " + lockModel.lock1
                                + " 锁2 " + lockModel.lock2
                                + " 锁3 " + lockModel.lock3
                                + " 锁4 " + lockModel.lock4
                                + " 锁5 " + lockModel.lock5
                                + " 锁6 " + lockModel.lock6
                                + " 锁7 " + lockModel.lock7
                                + " 锁8 " + lockModel.lock8
                                + " 锁9 " + lockModel.lock9
                                + " 锁10 " + lockModel.lock10
                                + " 锁11 " + lockModel.lock11
                                + " 锁12 " + lockModel.lock12);
                            AddRunData(lockModel);
                        }
;
                        break;
                    }
                case "34":
                    {
                        //         本命令只有按键申请解封开锁时才会用到，且
                        //         为实时请求命令，如遇 GPRS 网络不通，禁止将其当成
                        //         盲点数据保存。
                        cellData = cellData.Substring(1, 3);
                        int i = Convert.ToInt32(cellData, 16);
                        string lockStatus = Convert.ToString(i, (Int32)2).PadLeft(12, '0');
                        {
                            //位为 0 表示该子锁申请解封开锁，为 1 则表示该子锁为施封申请
                            string lock1 = lockStatus.Substring(11, 1);
                            string lock2 = lockStatus.Substring(10, 1);
                            string lock3 = lockStatus.Substring(9, 1);
                            string lock4 = lockStatus.Substring(8, 1);
                            string lock5 = lockStatus.Substring(7, 1);
                            string lock6 = lockStatus.Substring(6, 1);
                            string lock7 = lockStatus.Substring(5, 1);
                            string lock8 = lockStatus.Substring(4, 1);
                            string lock9 = lockStatus.Substring(3, 1);
                            string lock10 = lockStatus.Substring(2, 1);
                            string lock11 = lockStatus.Substring(1, 1);
                            string lock12 = lockStatus.Substring(0, 1);
                        }
                        break;
                    }
                case "35":
                    {
                        break;
                    }
                case "36":
                    {
                        try
                        {
                            //ShowMessageInWindow("执行液位、温度解析");       
                            int count = cellData.Length / 22;
                            for (int i = 0; i < count; i++)
                            {

                                string str = cellData.Substring(i * 22, 22);
                                string deviceNoStr = str.Substring(0, 2);
                                int deviceNo = Convert.ToInt32(deviceNoStr, 16);
                                if (deviceNo == 1)
                                {
                                    string ywStr = str.Substring(4, 8);
                                    double yw = StringToFloat(ywStr);
                                    string wdStr = str.Substring(14, 8);
                                    double wd = StringToFloat(wdStr);
                                    mod.YW1 = yw;
                                    mod.Temp1 = wd;
                                }
                                if (deviceNo == 2)
                                {
                                    string ywStr = str.Substring(4, 8);
                                    double yw = StringToFloat(ywStr);
                                    string wdStr = str.Substring(14, 8);
                                    double wd = StringToFloat(wdStr);
                                    mod.YW2 = yw;
                                    mod.Temp2 = wd;
                                }
                                if (deviceNo == 3)
                                {
                                    string ywStr = str.Substring(4, 8);
                                    double yw = StringToFloat(ywStr);
                                    string wdStr = str.Substring(14, 8);
                                    double wd = StringToFloat(wdStr);
                                    mod.YW3 = yw;
                                    mod.Temp3 = wd;
                                }
                                if (deviceNo == 4)
                                {
                                    string ywStr = str.Substring(4, 8);
                                    double yw = StringToFloat(ywStr);
                                    string wdStr = str.Substring(14, 8);
                                    double wd = StringToFloat(wdStr);
                                    mod.YW4 = yw;
                                    mod.Temp4 = wd;
                                }
                            }
                            mod.cmdType = 1;
                            AddRunYWData(mod);
                        }
                        catch (Exception ex)
                        {
                            string errorMsg = cellData;
                            ShowMessageInWindow("液位报错: " + ex.Message);
                        }

                    }
                defalt: break;
            }
            return mod;
        }

        /// <summary>
        /// 车机 扩展单元解析
        /// </summary>
        /// <param name="cellData"></param>
        /// <param name="Id"></param>
        /// <param name="mod"></param>
        /// <returns></returns>
        public ModelDevice CarCellDataPase(string cellData, int Id, ModelDevice mod)
        {
            string resultData = cellData;
            switch (Id)
            {
                case 1:
                    {
                        break;
                    }
                case 2:
                    {
                        string nIdStr = resultData.Substring(0, 2);
                        int nId = Convert.ToInt32(nIdStr, 16);
                        switch (nId)
                        {
                            case 1:
                                {
                                    mod.YW1 = Convert.ToUInt16(resultData.Substring(2, 4), 16);
                                    break;
                                }
                            case 2:
                                {
                                    mod.YW2 = Convert.ToUInt16(resultData.Substring(2, 4), 16);
                                    break;
                                }
                            case 3:
                                {
                                    mod.YW3 = Convert.ToUInt16(resultData.Substring(2, 4), 16);
                                    break;
                                }
                            case 4:
                                {
                                    mod.YW4 = Convert.ToUInt16(resultData.Substring(2, 4), 16);
                                    break;
                                }
                            case 5:
                                {
                                    mod.YW5 = Convert.ToUInt16(resultData.Substring(2, 4), 16);
                                    break;
                                }
                            case 6:
                                {
                                    mod.YW6 = Convert.ToUInt16(resultData.Substring(2, 4), 16);
                                    break;
                                }
                            case 7:
                                {
                                    mod.YW7 = Convert.ToUInt16(resultData.Substring(2, 4), 16);
                                    break;
                                }
                            case 8:
                                {
                                    mod.YW8 = Convert.ToUInt16(resultData.Substring(2, 4), 16);
                                    break;
                                }
                            case 9:
                                {
                                    mod.YW9 = Convert.ToUInt16(resultData.Substring(2, 4), 16);
                                    break;
                                }
                            case 10:
                                {
                                    mod.YW10 = Convert.ToUInt16(resultData.Substring(2, 4), 16);
                                    break;
                                }
                            default: break;
                        }
                        break;
                    }
                case 3:
                    {
                        string nIdStr = resultData.Substring(0, 2);
                        int nId = Convert.ToInt32(nIdStr, 16);
                        switch (nId)
                        {
                            case 1:
                                {
                                    mod.Temp1 = Convert.ToInt16(resultData.Substring(2, 4), 16) / 10d;
                                    break;
                                }
                            case 2:
                                {
                                    mod.Temp2 = Convert.ToInt16(resultData.Substring(2, 4), 16) / 10d;
                                    break;
                                }
                            case 3:
                                {
                                    mod.Temp3 = Convert.ToInt16(resultData.Substring(2, 4), 16) / 10d;
                                    break;
                                }
                            case 4:
                                {
                                    mod.Temp4 = Convert.ToInt16(resultData.Substring(2, 4), 16) / 10d;
                                    break;
                                }
                            case 5:
                                {
                                    mod.Temp5 = Convert.ToInt16(resultData.Substring(2, 4), 16) / 10d;
                                    break;
                                }
                            case 6:
                                {
                                    mod.Temp6 = Convert.ToInt16(resultData.Substring(2, 4), 16) / 10d;
                                    break;
                                }
                            case 7:
                                {
                                    mod.Temp7 = Convert.ToInt16(resultData.Substring(2, 4), 16) / 10d;
                                    break;
                                }
                            case 8:
                                {
                                    mod.Temp8 = Convert.ToInt16(resultData.Substring(2, 4), 16) / 10d;
                                    break;
                                }
                            case 9:
                                {
                                    mod.Temp9 = Convert.ToInt16(resultData.Substring(2, 4), 16) / 10d;
                                    break;
                                }
                            case 10:
                                {
                                    mod.Temp10 = Convert.ToInt16(resultData.Substring(2, 4), 16) / 10d;
                                    break;
                                }
                            default: break;
                        }
                        break;
                    }
                case 4:
                    {
                        mod.XF_Code = Convert.ToUInt16(resultData, 16);
                        break;
                    }
                case 5:
                    {
                        string switchData = Convert.ToString(Convert.ToInt32(resultData, 16), (Int32)2).PadLeft(8, '0');
                        mod.KND_status1 = Convert.ToUInt16(switchData.Substring(7, 1), 16);
                        mod.KND_status2 = Convert.ToUInt16(switchData.Substring(6, 1), 16);
                        break;
                    }
                case 6:
                    {
                        mod.KND_Temp = Convert.ToUInt16(resultData.Substring(2, 4), 16);
                        break;
                    }
                case 7:
                    {
                        mod.YYS_Code = Convert.ToInt32(resultData.Substring(0, 2), 16);
                        mod.d1 = resultData.Substring(2, 4);
                        mod.d2 = resultData.Substring(6, 4);
                        break;
                    }
                defalt: break;
            }
            return mod;
        }

        /// <summary>
        /// 锁控数据处理
        /// </summary>
        /// <param name="data">锁控数据</param>
        /// <param name="mod">ModelDevice 对象</param>
        public void LockDataHandle(string data, ModelDevice mod)
        {
            string frameHeader = "F33F";  //帧头
            string frameTail = "F44F";    //帧尾
            if (data.Length <= 18)
            { return; }

            //处理粘包情况
            int start = data.IndexOf(frameHeader);
            if (start < 0)
            {
                ShowMessageInWindow("不包含帧头，舍弃");
                return;
            }
            int end = data.IndexOf(frameTail);
            if (end < 0)
            {
                ShowMessageInWindow("不包含帧尾，舍弃");
                return;
            }
            if (end <= start)
            {
                string tempStr = data.Substring(start);
                end = tempStr.IndexOf(frameTail);
                if (end <= 0)
                {
                    ShowMessageInWindow("不包含帧尾，舍弃");
                    return;
                }
                start = 0;
                data = tempStr.Substring(start, end - start + 4);
            }
            else
            {
                data = data.Substring(start, end - start + 4);
            }

            string head = data.Substring(0, 4);
            string tail = data.Substring(data.Length - 4, 4);
            if (frameHeader.Equals(head) && frameTail.Equals(tail))
            {
                string addr = data.Substring(4, 4); //地址码
                string flag = data.Substring(8, 4); //返回类型标志

                //施解封返回
                if ("1166".Equals(flag))
                {

                    string isSuccess = data.Substring(12, 2);
                    if ("01".Equals(isSuccess))
                    {
                        ShowMessageInWindow(mod.DeviceName + " 施解封成功");
                        CarHandle carHandle = new CarHandle();
                        carHandle.deviceId = mod.DeviceId;
                        carHandle.deviceName = mod.DeviceName;
                        carHandle.handleName = "施解封";
                        carHandle.isCenter = "0";
                        carHandle.result = "成功";
                        AddHandleData(carHandle);
                        //Common.ExecuteNonQuery("update sys_control set status='成功',mark='1' where rtu_id='" + mod.rtuId + "' and mark='0'");
                    }
                    else if ("00".Equals(isSuccess))
                    {
                        ShowMessageInWindow(mod.DeviceName + " 施解封失败");
                        CarHandle carHandle = new CarHandle();
                        carHandle.deviceId = mod.DeviceId;
                        carHandle.deviceName = mod.DeviceName;
                        carHandle.handleName = "施解封";
                        carHandle.isCenter = "0";
                        carHandle.result = "失败";
                        AddHandleData(carHandle);
                    }
                    else
                    {
                        ShowMessageInWindow(mod.DeviceName + " 施解封异常，返回异常数据");
                    }
                }
                //心跳包 即锁控返回状态
                else if ("C9C9".Equals(flag))
                {
                    string lenStr = data.Substring(12, 2);
                    if (!"0D".Equals(lenStr))
                    {
                        ShowMessageInWindow(mod.DeviceName + " 长度不为0D,舍弃");
                        return;
                    }
                    string realData = data.Substring(14, 26);
                    byte[] dataTemp = Common.HexStringToByteArray(realData);
                    string result = Encoding.Default.GetString(dataTemp);
                    ShowMessageInWindow("心跳包返回ascii数据 " + result);
                    lockStatus lockStatus = new lockStatus();
                    lockStatus.deviceId = mod.DeviceId;
                    lockStatus.deviceName = mod.DeviceName;
                    lockStatus.rtuId = mod.rtuId;
                    lockStatus.data = result;
                    lockStatus.fullData = data;
                    // lockStatus.mainLock = result.Substring(12, 1);
                    lockStatus.lock1 = result.Substring(0, 1);
                    lockStatus.lock2 = result.Substring(1, 1);
                    lockStatus.lock3 = result.Substring(2, 1);
                    lockStatus.lock4 = result.Substring(3, 1);
                    lockStatus.lock5 = result.Substring(4, 1);
                    lockStatus.lock6 = result.Substring(5, 1);
                    lockStatus.lock7 = result.Substring(6, 1);
                    lockStatus.lock8 = result.Substring(7, 1);
                    lockStatus.lock9 = result.Substring(8, 1);
                    lockStatus.lock10 = result.Substring(9, 1);
                    lockStatus.lock11 = result.Substring(10, 1);
                    lockStatus.lock12 = result.Substring(11, 1);

                    ShowMessageInWindow(mod.DeviceName + " 主锁 " + lockStatus.mainLock
                        + " 锁1 " + lockStatus.lock1
                        + " 锁2 " + lockStatus.lock2
                        + " 锁3 " + lockStatus.lock3
                        + " 锁4 " + lockStatus.lock4
                        + " 锁5 " + lockStatus.lock5
                        + " 锁6 " + lockStatus.lock6
                        + " 锁7 " + lockStatus.lock7
                        + " 锁8 " + lockStatus.lock8
                        + " 锁9 " + lockStatus.lock9
                        + " 锁10 " + lockStatus.lock10
                        + " 锁11 " + lockStatus.lock11
                        + " 锁12 " + lockStatus.lock12);
                    AddRunData(lockStatus);
                }
                // 联机是否成功 可测试是否在线
                else if ("5354".Equals(flag))
                {
                    string isSuccess = data.Substring(12, 2);
                    if ("01".Equals(isSuccess))
                    {
                        ShowMessageInWindow(mod.DeviceName + " 联机成功");
                    }
                    else if ("00".Equals(isSuccess))
                    {
                        ShowMessageInWindow(mod.DeviceName + " 联机失败");
                    }
                    else
                    {
                        ShowMessageInWindow(mod.DeviceName + " 联机异常，返回异常数据");
                    }
                }
                //注册卡施解封
                else if ("CBCB".Equals(flag))
                {
                    string Idstr = data.Substring(14, 16);
                    byte[] dataTemp = Common.HexStringToByteArray(Idstr);
                    string Id = Encoding.Default.GetString(dataTemp);
                    string lockStatus = data.Substring(30, 2);
                    CarHandle carHandle = new CarHandle();
                    carHandle.deviceId = mod.DeviceId;
                    carHandle.deviceName = mod.DeviceName;
                    carHandle.carId = Id;
                    if ("30".Equals(lockStatus))
                    {
                        ShowMessageInWindow("注册卡： " + Id + " 解封");
                        carHandle.handleName = "卡解封";
                    }
                    if ("31".Equals(lockStatus))
                    {
                        ShowMessageInWindow("注册卡： " + Id + " 施封");
                        carHandle.handleName = "卡施封";
                    }
                    carHandle.data = data;
                    carHandle.result = "成功";
                    carHandle.isCenter = "1";
                    AddHandleData(carHandle);
                }
                //非注册卡施解封
                else if ("11AA".Equals(flag))
                {
                    //注意：0X30解封卡  0X31施封卡
                    //F3 3F FF FF 11 AA 09 31 32 33 34 35 36 37 38 31SunCheck F4 4F

                    string Idstr = data.Substring(14, 16);
                    byte[] dataTemp = Common.HexStringToByteArray(Idstr);
                    string Id = Encoding.Default.GetString(dataTemp);
                    string lockStatus = data.Substring(30, 2);
                    CarHandle carHandle = new CarHandle();
                    carHandle.deviceId = mod.DeviceId;
                    carHandle.deviceName = mod.DeviceName;
                    carHandle.carId = Id;
                    if ("30".Equals(lockStatus))
                    {
                        carHandle.result = "失败，非注册卡 解封";
                    }
                    if ("31".Equals(lockStatus))
                    {
                        carHandle.result = "失败，非注册卡 施封";
                    }
                    carHandle.data = data;
                    carHandle.isCenter = "1";
                    AddHandleData(carHandle);

                }
                // 锁的信号质量输出 此条数据每5分钟发送一条.
                //F33FFFFF22000C00000000000000940000000040F44F
                else if ("2200".Equals(flag))
                {
                    string realData = data.Substring(14, 24);
                    int lock1 = Convert.ToInt32(realData.Substring(0, 2), 16);
                    int lock2 = Convert.ToInt32(realData.Substring(2, 2), 16);
                    int lock3 = Convert.ToInt32(realData.Substring(4, 2), 16);
                    int lock4 = Convert.ToInt32(realData.Substring(6, 2), 16);
                    int lock5 = Convert.ToInt32(realData.Substring(8, 2), 16);
                    int lock6 = Convert.ToInt32(realData.Substring(10, 2), 16);
                    int lock7 = Convert.ToInt32(realData.Substring(12, 2), 16);
                    int lock8 = Convert.ToInt32(realData.Substring(14, 2), 16);
                    int lock9 = Convert.ToInt32(realData.Substring(16, 2), 16);
                    int lock10 = Convert.ToInt32(realData.Substring(18, 2), 16);
                    int lock11 = Convert.ToInt32(realData.Substring(20, 2), 16);
                    int lock12 = Convert.ToInt32(realData.Substring(22, 2), 16);
                    ShowMessageInWindow("12分锁信号质量 " + lock1 + " " + lock2 + " " + lock3 + " " + lock4 + " " + lock5 + " " + lock6 + " "
                        + lock7 + " " + lock8 + " " + lock9 + " " + lock10 + " " + lock11 + " " + lock12);
                }
                else if ("11BB".Equals(flag))
                {
                    string workFlag = data.Substring(12, 2);
                    if ("00".Equals(workFlag))
                    {
                        ShowMessageInWindow("修改工作模式失败！");
                    }
                    if ("01".Equals(workFlag))
                    {
                        ShowMessageInWindow("修改工作模式成功！");
                    }
                }
                else if ("1188".Equals(flag))
                {
                    string workFlag = data.Substring(12, 2);
                    if ("00".Equals(workFlag))
                    {
                        ShowMessageInWindow("Bind Card 失败！");
                    }
                    if ("01".Equals(workFlag))
                    {
                        ShowMessageInWindow("Bind Card 成功！");
                    }
                }
                else if ("1010".Equals(flag))
                {
                    string workFlag = data.Substring(12, 2);
                    if ("00".Equals(workFlag))
                    {
                        ShowMessageInWindow("Bind Lock 失败！");
                    }
                    if ("01".Equals(workFlag))
                    {
                        ShowMessageInWindow("Bind Lock 成功！");
                    }
                }
                else if ("1011".Equals(flag))
                {
                    string workFlag = data.Substring(12, 2);
                    if ("00".Equals(workFlag))
                    {
                        ShowMessageInWindow("delete Lock 失败！");
                    }
                    if ("01".Equals(workFlag))
                    {
                        ShowMessageInWindow("delete Lock 成功！");
                    }
                }
                //读取锁id 成功 F3 3F FF FF 11 11 07 00 31 30 30 30 30 30 B8 F4 4F
                //失败  F3 3F FF FF 11 11 00 E0 F4 4F
                else if ("1111".Equals(flag))
                {
                    string workFlag = data.Substring(12, 2);
                    if ("00".Equals(workFlag))
                    {
                        int lockSeq = Convert.ToInt32(data.Substring(14, 2));
                        ShowMessageInWindow("读取" + lockSeq + "锁id 失败！");
                    }
                    if ("07".Equals(workFlag))
                    {
                        int lockSeq = Convert.ToInt32(data.Substring(14, 2));
                        string lockIdStr = data.Substring(16, 12);
                        byte[] byteData = Common.HexStringToByteArray(lockIdStr);
                        string lockId = new ASCIIEncoding().GetString(byteData);
                        ShowMessageInWindow("读取" + lockSeq + "锁id 成功,锁id为 " + lockId);
                    }
                }
                else
                {
                    ShowMessageInWindow(mod.DeviceName + "不符合任何标志位，返回异常数据 " + data);
                }

            }
            else
            {
                ShowMessageInWindow("不符合帧结构，返回数据为 " + data);
            }
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="s_socket">指定客户端socket</param>
        /// <param name="bytes">发送消息</param>
        public void Send(Socket c_socket, byte[] bytes, string ip)
        {
            try
            {
                //发送
                c_socket.BeginSend(bytes, 0, bytes.Length, SocketFlags.None, asyncResult =>
                {
                    try
                    {
                        //完成消息发送
                        int len = c_socket.EndSend(asyncResult);
                    }
                    catch (Exception ex)
                    {
                        if (c_socket != null)
                        {
                            c_socket.Close();
                            c_socket = null;
                        }
                        ShowMessageInWindow("ip: " + ip + "error ex=" + ex.Message + " " + ex.StackTrace);
                    }
                }, null);

            }
            catch (Exception ex)
            {
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message);//将出错信息写入错误日志   
                ShowMessageInWindow(MethodBase.GetCurrentMethod().Name + " ip: " + ip + ex.Message);
                SafeClose(c_socket);
                removeSocketClient(c_socket.Handle);
            }
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="s_socket">指定客户端socket</param>
        /// <param name="bytes">发送消息</param>
        public void Send(Socket c_socket, byte[] bytes)
        {
            try
            {
                //发送
                c_socket.BeginSend(bytes, 0, bytes.Length, SocketFlags.None, asyncResult =>
                {
                    try
                    {
                        //完成消息发送
                        int len = c_socket.EndSend(asyncResult);
                    }
                    catch (Exception ex)
                    {
                        if (c_socket != null)
                        {
                            c_socket.Close();
                            c_socket = null;
                        }
                        ShowMessageInWindow("error ex=" + ex.Message + " " + ex.StackTrace);
                    }
                }, null);

            }
            catch (Exception ex)
            {
                if (c_socket != null)
                {
                    c_socket.Close();
                    c_socket = null;
                }
            }
        }

        public void removeSocketClient(IntPtr intptr)
        {
            lock (locker)
            {
                if (serverSessionPool.ContainsKey(intptr))
                {
                    serverSessionPool.Remove(intptr);
                }
            }
            Invoke(new Action(delegate
            {
                for (int i = 0; i < socketClinetTree.Nodes.Count; i++)
                {
                    if (socketClinetTree.Nodes[i].Tag.Equals(intptr))
                    {
                        socketClinetTree.Nodes.Remove(socketClinetTree.Nodes[i]);
                    }
                }
                for (int i = 0; i < comboBox1.Items.Count; i++)
                {
                    if (comboBox1.Items[i].Equals(intptr))
                    {
                        comboBox1.Items.Remove(comboBox1.Items[i]);
                    }
                }
            }));
        }

        /// <summary>
        /// Close the socket safely.
        /// </summary>
        /// <param name="socket">The socket.</param>
        public void SafeClose(Socket socket)
        {
            if (socket == null)
                return;

            if (!socket.Connected)
                return;

            try
            {
                socket.Shutdown(SocketShutdown.Both);
                Delay(200);

            }
            catch
            {
            }
            try
            {
                socket.Close();
            }
            catch
            {
            }
        }


        /// <summary>
        /// 关闭所有socket
        /// </summary>
        /// <param name="dic"></param>
        public void CloseAllSocket(Dictionary<IntPtr, Session> dic)
        {
            List<IntPtr> keyList = new List<IntPtr>(serverSessionPool.Keys);
            for (int i = 0; i < serverSessionPool.Count(); i++)
            {
                SafeClose(serverSessionPool[keyList[i]].SockeClient);
            }
        }


        #region 窗体事件方法
        /// <summary>
        /// 双击图标事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void IcnSys_Click(object sender, EventArgs e)
        {
            try
            {
                Visible = true;//显示窗体
                ShowInTaskbar = true;//不在任务栏显示
                WindowState = FormWindowState.Normal;//窗体大小
            }
            catch (Exception ex)
            {
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message);//将出错信息写入错误日志
            }
        }
        /// <summary>
        /// 右键菜单退出事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void TsbtnExit_Click(object sender, EventArgs e)
        {
            try
            {
                SafeClose(Socket);
                CloseAllSocket(serverSessionPool);

                Close();//关闭窗体
                Dispose();//释放资源
                Application.Exit();//退出程序
            }
            catch (Exception ex)
            {
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message);//将出错信息写入错误日志
            }
        }
        /// <summary>
        /// 窗口大小改变事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void FrmMain_SizeChanged(object sender, EventArgs e)
        {
            try
            {
                //最小化时只显示图标
                if (WindowState == FormWindowState.Minimized)
                {
                    ShowInTaskbar = false;//不在任务栏显示
                    icnSys.Visible = true;//在任务栏通知区域显示图标
                }
            }
            catch (Exception ex)
            {
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message);//将出错信息写入错误日志
            }
        }
        /// <summary>
        /// 关闭窗体时默认为最小化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                e.Cancel = true;//取消关闭事件
                WindowState = FormWindowState.Minimized;//最小化窗口
                Visible = false;//不显示窗体
                icnSys.Visible = true;//在任务栏通知区域显示图标
            }
            catch (Exception ex)
            {
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message);//将出错信息写入错误日志
            }
        }

        /// <summary>
        /// 退出-关闭窗体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void TsbtnClose_Click(object sender, EventArgs e)
        {
            try
            {
                Thread.Sleep(1000);
                CloseAllSocket(serverSessionPool);
                //     SafeClose(Socket);
                try
                {
                    Socket.Shutdown(SocketShutdown.Both);
                    Delay(200);
                }
                catch (Exception ex)
                {
                }
                try
                {
                    Socket.Close();
                }

                catch (Exception ex)
                {
                }
                Close();//关闭窗体
                Dispose();//释放资源
                Application.Exit();//退出程序
            }
            catch (Exception ex)
            {
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message);//将出错信息写入错误日志
            }
        }

        #endregion


        #region 保存数据写入文本文件
        /// <summary>
        /// 将消息保存到文件中
        /// </summary>
        /// <param name="strMessage">消息内容</param>
        private void SaveMessage(string strMessage)
        {
            try
            {
                //没有消息内容时返回
                if (string.IsNullOrEmpty(strMessage))
                {
                    return;
                }
                //默认保存文件路径
                string filePath = Directory.GetCurrentDirectory() + "\\Message";
                if (!Directory.Exists(filePath))
                {
                    Directory.CreateDirectory(filePath);//创建目录
                }
                //取系统时间作为文件名
                string fileName = filePath + "\\Message" + DateTime.Now.Year.ToString() + "-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Day.ToString() + ".txt";
                if (!File.Exists(fileName))
                {
                    File.CreateText(fileName).Close();//创建文本文件后关闭
                    //每天创建新文件时先清空窗体接收消息文本内容
                    Invoke(new Action(delegate
                    {
                        txtMessage.Text = "";
                    }));
                }
                //将消息内容写入文件中
                File.AppendAllText(fileName, strMessage + "\r\n");
            }
            catch (Exception ex)
            {
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message);//将出错信息写入错误日志
            }
        }

        #endregion

        #region 在消息区域显示数据
        public void ShowMessage(string message)
        {
            txtMessage.Text = "\r\n" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss =>") + message + txtMessage.Text;
        }

        public void ShowMessageInWindow(string message)
        {
            this.Invoke(myDeleteage, message);
        }

        #endregion

        /// <summary>
        /// 计时器，等待指定时间
        /// </summary>
        /// <param name="milliSecond"></param>
        public static void Delay(int milliSecond)
        {
            int start = Environment.TickCount;
            while (Math.Abs(Environment.TickCount - start) < milliSecond)
            {
                Application.DoEvents();
            }
        }

        /// <summary>
        /// 10进制转为16进制，转为 XX XX XX XX格式
        /// </summary>
        /// <param name="s">字符串类型</param>
        /// <returns></returns>
        public string DEC_to_DWORD(string s)
        {
            int val = int.Parse(s);
            string value = val.ToString("X");
            string result = "";
            if (value.Length == 1)

            {
                result = "00 00 00 0" + value.ToUpper();
            }
            else if (value.Length == 2)
            {
                result = "00 00 00 " + value.ToUpper();
            }
            else if (value.Length == 3)
            {
                result = "00 00 0" + value;
            }
            else if (value.Length == 4)
            {
                result = "00 00 " + value;
            }
            else if (value.Length == 5)
            {
                result = "00 0" + value;
            }
            else if (value.Length == 6)
            {
                result = "00 " + value;
            }
            else if (value.Length == 7)
            {
                result = "0" + value;
            }
            else
            {
                result = value;
            }
            return result;
        }


        /// <summary>
        /// 10进制转为16进制，转为 XX XX格式
        /// </summary>
        /// <param name="s">字符串类型</param>
        /// <returns></returns>
        public string DEC_to_HEX(string s)
        {
            //     string value = val.ToString("X");  int类型转为string 16进制类型
            int val = int.Parse(s);
            string value = val.ToString("X");
            string result = "";
            if (value.Length == 1)

            {
                result = "00 0" + value.ToUpper();
            }
            else if (value.Length == 2)
            {
                result = "00 " + value.ToUpper();
            }
            else if (value.Length == 3)
            {
                result = "0" + value;
            }
            else
            {
                result = value;
            }
            return result;
        }

        /// <summary>
        /// 10进制转为16进制，转为 XX XX格式
        /// </summary>
        /// <param name="val">int 类型</param>
        /// <returns></returns>
        public string DEC_to_HEX(int val)
        {
            string value = val.ToString("X");
            string result = "";
            if (value.Length == 1)

            {
                result = "00 0" + value.ToUpper();
            }
            else if (value.Length == 2)
            {
                result = "00 " + value.ToUpper();
            }
            else if (value.Length == 3)
            {
                result = "0" + value.Substring(0, 1) + " " + value.Substring(1, 2);
            }
            else
            {
                result = value;
            }
            return result;
        }

        /// <summary>
        /// 10进制转为16进制，转为 XX格式
        /// </summary>
        /// <param name="s">字符串类型</param>
        /// <returns></returns>
        public string DEC_to_2HEX(string s)
        {
            //     string value = val.ToString("X");  int类型转为string 16进制类型
            int val = int.Parse(s);
            string value = val.ToString("X");
            string result = "";
            if (value.Length == 1)
            {
                result = "0" + value;
            }
            else
            {
                result = value;
            }
            return result;
        }



        /// <summary>
        /// 得到CRC-16
        /// </summary>
        /// <param name="cmd">指令</param>
        /// <returns></returns>
        public string Full_Crc(string cmd)
        {
            string result = "";
            byte[] bytes = Common.HexStringToByteArray(cmd);
            byte[] crc16 = Crc16.crc16_bytes(bytes, bytes.Count());
            result = Common.ByteArrayToHexString(crc16, 0, crc16.Count());
            return result;
        }

        /// <summary>  
        /// 字符串转为浮点数
        /// </summary>  
        /// <param name="s" />字符串  
        /// <returns>浮点数</returns>  
        private double StringToFloat(string s)
        {
            s = s.Replace(" ", "");
            Byte[] bytes = Common.HexStringToByteArray(s);
            bytes = bytes.Reverse().ToArray();  //反序
            float fNum = BitConverter.ToSingle(bytes, 0);
            return Math.Round(fNum, 2);
        }

        // <summary>  
        /// 字符串转为双精度浮点数
        /// </summary>  
        /// <param name="s" />字符串
        /// <returns>返回双精度浮点数</returns>  
        private double StringToDouble(string s)
        {
            s = s.Replace(" ", "");
            Byte[] bytes = Common.HexStringToByteArray(s);
            bytes = bytes.Reverse().ToArray();  //反序
            double fNum = BitConverter.ToDouble(bytes, 0);
            return Math.Round(fNum, 2);
        }

        /// <summary>  
        /// 将BCD一字节数据转换到byte 十进制数据  
        /// </summary>  
        /// <param name="b" />字节数  
        /// <returns>返回转换后的BCD码</returns>  
        public string ConvertBCDToString(string s)
        {
            Byte b = Convert.ToByte(s, 2);
            //高四位  
            byte b1 = (byte)((b >> 4) & 0xF);
            //低四位  
            byte b2 = (byte)(b & 0xF);

            int i = (byte)(b1 * 10 + b2);
            return i.ToString();
        }


        /// <summary>
        /// 获得text 行数
        /// </summary>
        /// <param name="text">textbox对象的text值</param>
        /// <returns>行数</returns>
        public int getTextBoxCount(string text)
        {
            //使用正则表达式命名空间，并把要进行配对的字符串放入其中
            System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(@"\r\n");
            //声明变量用来接收得到的行数，因为最后一行结尾没有换行，所以需要加1
            int count = reg.Matches(text).Count;
            //输出行数
            return count;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if ("开始监听".Equals(switchButton.Text))
            {
                listenerInit();
                timer1.Start();
            }
            else
            {
                timer1.Stop();
                SafeClose(Socket);
                CloseAllSocket(serverSessionPool);

                try
                {
                    Socket.Shutdown(SocketShutdown.Both);
                    Delay(200);
                }
                catch (Exception ex)
                {
                }
                try
                {
                    Socket.Close();
                }

                catch (Exception ex)
                {
                }
                switchButton.Text = "开始监听";

                Invoke(new Action(delegate
                {
                    socketClinetTree.Nodes.Clear();
                    comboBox1.Items.Clear();
                }));

            }
        }


        private void socketClinetTree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            TreeNode treeNode = e.Node;
            IntPtr handle = (IntPtr)treeNode.Tag;
            comboBox1.Text = handle.ToString();
            infoLabel.Text = "设备详情： " + serverSessionPool[handle].DeviceName;
        }

        public Session getSessionByRtuId(string rtuId)
        {
            Session session = null;
            lock (locker)
            {
                List<IntPtr> keyList = new List<IntPtr>(serverSessionPool.Keys);
                for (int i = 0; i < serverSessionPool.Count(); i++)
                {
                    if (serverSessionPool.ContainsKey(keyList[i]))
                    {
                        Session temp = serverSessionPool[keyList[i]];
                        if (rtuId.Equals(temp.RtuId))
                        {
                            session = temp;
                            break;
                        }
                    }
                }
            }
            return session;
        }

        public Session getSessionBySocketHandle(IntPtr intPtr)
        {
            Session session = null;
            lock (locker)
            {
                if (serverSessionPool.ContainsKey(intPtr))
                {
                    session = serverSessionPool[intPtr];
                }
            }
            return session;
        }

        public Session getSessionBySocketIp(string ip)
        {
            Session session = null;
            lock (locker)
            {
                List<IntPtr> keyList = new List<IntPtr>(serverSessionPool.Keys);
                for (int i = 0; i < serverSessionPool.Count(); i++)
                {
                    if (serverSessionPool.ContainsKey(keyList[i]))
                    {
                        Session temp = serverSessionPool[keyList[i]];
                        if (ip.Equals(temp.IP))
                        {
                            session = temp;
                            break;
                        }
                    }
                }
            }
            return session;
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            InitForm initForm = new InitForm();
            initForm.Show();
        }

        public class reportData
        {
            public string deviceId { get; set; }
            public string deviceName { get; set; }
            public string reportType { get; set; }
            public string reportTypeName { get; set; }
            public string handleId { get; set; }
            public string fullCmd { get; set; }
            public string cmd { get; set; }
        }

        public class alarmData
        {
            public string deviceId { get; set; }
            public string name { get; set; }
            public string type { get; set; }
            public string alarm_status { get; set; }
            public int alarm_type { get; set; }
        }

        public class lockStatus
        {
            public string deviceId { get; set; }
            public string deviceName { get; set; }
            public string rtuId { get; set; }
            public string data { get; set; }
            public string fullData { get; set; }
            public string mainLock { get; set; }
            public string lock1 { get; set; }
            public string lock2 { get; set; }
            public string lock3 { get; set; }
            public string lock4 { get; set; }
            public string lock5 { get; set; }
            public string lock6 { get; set; }
            public string lock7 { get; set; }
            public string lock8 { get; set; }
            public string lock9 { get; set; }
            public string lock10 { get; set; }
            public string lock11 { get; set; }
            public string lock12 { get; set; }
        }

        public class CarHandle
        {
            public string deviceId { get; set; }
            public string deviceName { get; set; }
            public string data { get; set; }
            public string carId { get; set; }
            public string handleName { get; set; }

            /// <summary>
            /// 0 中心操作，1 卡操作
            /// </summary>
            public string isCenter { get; set; }

            public string result { get; set; }
        }

        private void label3_Click(object sender, EventArgs e)
        {
            string mainlockStatus = "";
            string lock1Status = "";
            string lock2Status = "";
            string lock3Status = "";
            string lock4Status = "";
            string lock5Status = "";
            string lock6Status = "";
            string lock7Status = "";
            string lock8Status = "";
            string lock9Status = "";
            string lock10Status = "";
            string lock11Status = "";
            string lock12Status = "";
            if (mainLockCheckbox.Checked)
            {
                mainlockStatus = "30";
            }
            else
            {
                mainlockStatus = "31";
            }
            if (lock1Checkbox.Checked)
            {
                lock1Status = "30";
            }
            else
            {
                lock1Status = "31";
            }

            if (lock2Checkbox.Checked)
            {
                lock2Status = "30";
            }
            else
            {
                lock2Status = "31";
            }
            if (lock3Checkbox.Checked)
            {
                lock3Status = "30";
            }
            else
            {
                lock3Status = "31";
            }
            if (lock4Checkbox.Checked)
            {
                lock4Status = "30";
            }
            else
            {
                lock4Status = "31";
            }
            if (lock5Checkbox.Checked)
            {
                lock5Status = "30";
            }
            else
            {
                lock5Status = "31";
            }
            if (lock6Checkbox.Checked)
            {
                lock6Status = "30";
            }
            else
            {
                lock6Status = "31";
            }
            if (lock7Checkbox.Checked)
            {
                lock7Status = "30";
            }
            else
            {
                lock7Status = "31";
            }
            if (lock8Checkbox.Checked)
            {
                lock8Status = "30";
            }
            else
            {
                lock8Status = "31";
            }
            if (lock9Checkbox.Checked)
            {
                lock9Status = "30";
            }
            else
            {
                lock9Status = "31";
            }
            if (lock10Checkbox.Checked)
            {
                lock10Status = "30";
            }
            else
            {
                lock10Status = "31";
            }
            if (lock11Checkbox.Checked)
            {
                lock11Status = "30";
            }
            else
            {
                lock11Status = "31";
            }
            if (lock12Checkbox.Checked)
            {
                lock12Status = "30";
            }
            else
            {
                lock12Status = "31";
            }
            if (comboBox1.SelectedItem == null)
            {
                MessageBox.Show("请选择设备");
                return;
            }
            IntPtr intPtr = (IntPtr)comboBox1.SelectedItem;
            Session session = serverSessionPool[intPtr];
            string addr = "FF FF";
            if ("".Equals(addr) || addr == null)
            {
                ShowMessageInWindow("发送指令异常，还未获得此客户端的地址码");
                return;
            }
            string cmd = addr + " 11 66" + " 15" + mainlockStatus + " 31 32 33 34 35 36 37 38 " +
                lock1Status + lock2Status + lock3Status + lock4Status + lock5Status + lock6Status + lock7Status + lock8Status +
                lock9Status + lock10Status + lock11Status + lock12Status;
            string sunCheck = SunCheck(cmd);
            cmd = "F1 1F" + cmd + " " + sunCheck + " F2 2F";
            byte[] data = Common.HexStringToByteArray(cmd);
            cmd = Common.ByteArrayToHexString(data, 0, data.Length);
            ShowMessageInWindow("发送指令：" + cmd);
            Send(session.SockeClient, data, session.IP);

        }


        /// <summary>
        /// 文本指令发送触发事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void label7_Click(object sender, EventArgs e)
        {
            IntPtr intPtr = (IntPtr)comboBox1.SelectedItem;
            Session session = serverSessionPool[intPtr];
            string cmd = cmdTextbox.Text;
            byte[] data = Common.HexStringToByteArray(cmd);
            cmd = Common.ByteArrayToHexString(data, 0, data.Length);
            ShowMessageInWindow("发送指令：" + cmd);
            Send(session.SockeClient, data, session.IP);
        }

        private void AddReportData(reportData mod)
        {
            string sqlText = "";
            try
            {

                sqlText = string.Format("insert into report_data (device_id,device_name,report_type,report_type_name,handle_id,stime,full_cmd,cmd) "
                                                + " values ('{0}','{1}','{2}','{3}','{4}',TO_DATE('{5}','yyyy-mm-dd hh24:mi:ss'),'{6}','{7}')",
                                                    mod.deviceId, mod.deviceName, mod.reportType, mod.reportTypeName, mod.handleId, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), mod.fullCmd, mod.cmd);
                int intResult1 = Common.ExecuteNonQuery(sqlText);

                if (intResult1 >= 1)
                {
                    ShowMessageInWindow("插入成功");
                }

            }
            catch (Exception ex)
            {
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message + "\r\n" + sqlText);//将出错信息写入错误日志
                ShowMessageInWindow("插入数据失败 " + ex.Message + "\r\n" + sqlText);
            }
        }

        private void AddSearchLockData(LockModel mod)
        {
            string sqlText = "";
            try
            {

                sqlText = string.Format("insert into DEVICE_SEARCH_LOCK_DATA (DEVICE_ID,DEVICE_NAME,CMD_DATA,LOCK_JSON) "
                                                + " values ('{0}','{1}','{2}','{3}')",
                                                    mod.deviceId, mod.deviceName, mod.cmdData, mod.lockJson);
                int intResult1 = Common.ExecuteNonQuery(sqlText);

                if (intResult1 >= 1)
                {
                    ShowMessageInWindow("插入成功");
                }

            }
            catch (Exception ex)
            {
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message + "\r\n" + sqlText);//将出错信息写入错误日志
                ShowMessageInWindow("插入数据失败 " + ex.Message + "\r\n" + sqlText);
            }
        }

        private void AddArgData(ArgModel mod)
        {
            string sqlText = "";
            try
            {

                sqlText = string.Format("insert into device_arg_data (DEVICE_ID,DEVICE_NAME,SBJG,MAIN_IP,BF_IP,PORT,HEART_BEAT,APN_NAME,APN_USER,APN_PASSWORD,SK_PASSWORD,DRIVER_PASSWORD" +
                    ",LOCK_NUM1,LOCK_NUM2,LOCK_NUM3,LOCK_NUM4,LOCK_NUM5,LOCK_NUM6,device_code) "
                                                + " values ('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}','{14}','{15}','{16}','{17}','{18}')",
                                                    mod.deviceId, mod.deviceName, mod.sbjg, mod.mainIp, mod.bfIp, mod.port, mod.heartBeat, mod.apnName, mod.apnUser,
                                                    mod.apnPassword, mod.skPassword, mod.driverPassword, mod.lockNum1, mod.lockNum2, mod.lockNum3, mod.lockNum4, mod.lockNum5, mod.lockNum6, mod.deviceCode);
                int intResult1 = Common.ExecuteNonQuery(sqlText);

                if (intResult1 >= 1)
                {
                    ShowMessageInWindow("插入成功");
                }

            }
            catch (Exception ex)
            {
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message + "\r\n" + sqlText);//将出错信息写入错误日志
                ShowMessageInWindow("插入数据失败 " + ex.Message + "\r\n" + sqlText);
            }
        }

        private void AddAlarmData(alarmData mod)
        {
            string sqlText = "";
            try
            {

                sqlText = string.Format("insert into alarm (name,stime,type,device_id) "
                                                + " values ('{0}',TO_DATE('{1}','yyyy-mm-dd hh24:mi:ss'),'{2}','{3}')",
                                                    mod.name, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), mod.type, mod.deviceId);
                int intResult1 = Common.ExecuteNonQuery(sqlText);

                if (intResult1 >= 1)
                {
                    ShowMessageInWindow("插入成功");
                }

            }
            catch (Exception ex)
            {
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message + "\r\n" + sqlText);//将出错信息写入错误日志
                ShowMessageInWindow("插入数据失败 " + ex.Message + "\r\n" + sqlText);
            }
        }

        private void AddRunData(lockStatus mod)
        {
            string sqlText1 = "";
            try
            {

                sqlText1 = string.Format("insert into LOCK_DATA (DEVICE_ID,DEVICE_NAME,DATA,MAIN_LOCK,LOCK1,LOCK2,LOCK3,LOCK4,LOCK5,LOCK6,LOCK7,LOCK8,LOCK9,LOCK10,LOCK11,LOCK12,STIME,full_data,rtu_id) "
                                                + " values ('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}','{14}','{15}',TO_DATE('{16}','yyyy-mm-dd hh24:mi:ss'),'{17}','{18}')",
                                                    mod.deviceId, mod.deviceName, mod.data, mod.mainLock, mod.lock1, mod.lock2, mod.lock3, mod.lock4, mod.lock5, mod.lock6, mod.lock7, mod.lock8, mod.lock9, mod.lock10, mod.lock11, mod.lock12, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), mod.fullData, mod.rtuId);
                int intResult1 = Common.ExecuteNonQuery(sqlText1);

                if (intResult1 >= 1)
                {
                    ShowMessageInWindow("插入成功");
                }

            }
            catch (Exception ex)
            {
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message + "\r\n" + sqlText1);//将出错信息写入错误日志
                ShowMessageInWindow("插入数据失败 " + ex.Message + "\r\n" + sqlText1);
            }
        }

        private void AddRunCommonData(ModelDevice mod)
        {
            string sqlText1 = "";
            try
            {

                sqlText1 = string.Format("insert into common_data (DEVICE_ID,DEVICE_NAME,FULL_DATA,OIL_QUALITY_PER,RTU_ID,LNG,LAT,POS_MODEL,LEVEL1,LEVEL2,LEVEL3,LEVEL4,TEMPERATURE1,TEMPERATURE2,TEMPERATURE3,TEMPERATURE4,YW_SWITCH1,YW_SWITCH2,YW_SWITCH3,YW_SWITCH4,GXZJ,LIGHT_SWITCH,MAIN_JRB1_SWITCH,MAIN_JRB2_SWITCH,MAIN_JRB3_SWITCH,MAIN_JRB4_SWITCH,ASSIS_JRB1_SWITCH,ASSIS_JRB2_SWITCH,ASSIS_JRB3_SWITCH,ASSIS_JRB4_SWITCH,stime,v,DIREACTION,LI_CHENG,DOORSENSOR,is_located,cmd_type) "
                                                + " values ('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}','{14}','{15}','{16}','{17}','{18}','{19}','{20}','{21}','{22}','{23}','{24}','{25}','{26}','{27}','{28}','{29}',TO_DATE('{30}','yyyy-mm-dd hh24:mi:ss'),'{31}','{32}','{33}','{34}','{35}','{36}')",
                                                    mod.DeviceId, mod.DeviceName, mod.fullData, mod.oilQuantityPercent, mod.rtuId, mod.LNG, mod.LAT, mod.posModel, mod.YW1, mod.YW2, mod.YW3, mod.YW4, mod.Temp1, mod.Temp2, mod.Temp3, mod.Temp4, mod.YW_Switch1, mod.YW_Switch2, mod.YW_Switch3, mod.YW_Switch4, mod.GXZJ, mod.Light_Switch, mod.Main_JRB1_switch, mod.Main_JRB2_switch, mod.Main_JRB3_switch, mod.Main_JRB4_switch, mod.Assis_JRB1_switch, mod.Assis_JRB2_switch, mod.Assis_JRB3_switch, mod.Assis_JRB4_switch, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), mod.V, mod.Direction, mod.LI_CHENG, mod.DoorSensor, mod.isLocated, mod.cmdType);
                int intResult1 = Common.ExecuteNonQuery(sqlText1);

                if (intResult1 >= 1)
                {
                    ShowMessageInWindow("插入成功");
                }

            }
            catch (Exception ex)
            {
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message + "\r\n" + sqlText1);//将出错信息写入错误日志
                ShowMessageInWindow("插入数据失败 " + ex.Message + "\r\n" + sqlText1);
            }
        }


        private void AddHandleData(CarHandle mod)
        {
            string sqlText1 = "";
            try
            {

                sqlText1 = string.Format("insert into handle_data (DEVICE_ID,DEVICE_NAME,DATA,CAR_ID,HANDLE_NAME,STIME,is_center,result) "
                                                + " values ('{0}','{1}','{2}','{3}','{4}',TO_DATE('{5}','yyyy-mm-dd hh24:mi:ss'),'{6}','{7}')",
                                                    mod.deviceId, mod.deviceName, mod.data, mod.carId, mod.handleName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), mod.isCenter, mod.result);
                int intResult1 = Common.ExecuteNonQuery(sqlText1);

                if (intResult1 >= 1)
                {
                    ShowMessageInWindow("插入成功");
                }

            }
            catch (Exception ex)
            {
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message + "\r\n" + sqlText1);//将出错信息写入错误日志
                ShowMessageInWindow("插入数据失败 " + ex.Message + "\r\n" + sqlText1);
            }
        }

        /// <summary>
        /// 通过帧头帧尾获得有效的数据
        /// </summary>
        public List<string> getRealData(string s)
        {
            //帧头 F3 3F
            //帧尾 F4 4F
            //  string s = "F3 3F FF FF 22 00 0C 00 00 00 00 00 00 00 A1 00 00 00 00 33 F4 4F F3 3F 11 22 22 00 0C 00 00 00 00 00 00 00 A1 00 00 00 00 33 F4 4F";
            s = s.Replace(" ", "");

            List<string> result = new List<string>();
            string temp = s;
            do
            {
                int start = 0;
                int end = 0;
                start = temp.IndexOf("F33F");
                end = temp.IndexOf("F44F");
                if (end > start)
                {
                    string ss = temp.Substring(start, end - start + 4);
                    result.Add(ss);
                    temp = temp.Substring(end + 4);
                }
                else
                {
                    temp = temp.Substring(start);
                }

            } while (temp.IndexOf("F33F") >= 0 && temp.IndexOf("F44F") > 0);
            return result;

        }

        public void reortDicInit()
        {
            reportTypeDic.Add("0", "定时");
            reportTypeDic.Add("1", "车辆行驶自动施封");
            reportTypeDic.Add("2", "锁控被拆");
            reportTypeDic.Add("3", "按键申请");
            reportTypeDic.Add("4", "RFID 施封");
            reportTypeDic.Add("5", "RFID 解封");
            reportTypeDic.Add("6", "SMS 施封");
            reportTypeDic.Add("7", "SMS 解封");
            reportTypeDic.Add("8", "终端状态变更");
            reportTypeDic.Add("9", "非注册卡施封");
            reportTypeDic.Add("A", "非注册卡解封");
            reportTypeDic.Add("B", "注册卡施封");
            reportTypeDic.Add("C", "注册卡解封");
            reportTypeDic.Add("D", "应急密码解封 ");
            reportTypeDic.Add("E", "司机卡");
            reportTypeDic.Add("F", "平台施封");
            reportTypeDic.Add("G", "平台解封");
            reportTypeDic.Add("H", "ACC 上电自动施封");
            reportTypeDic.Add("I", "震动施封");
            reportTypeDic.Add("J", "订单结束申请");
            reportTypeDic.Add("K", "注册开锁卡");
            reportTypeDic.Add("L", "施封下有子锁被解开（异常变化）");
            reportTypeDic.Add("M", "有子锁被拆开（异常变化）");
            reportTypeDic.Add("N", "有子锁通讯超时（异常变化）");
            reportTypeDic.Add("O", "子锁正常状态变更（正常变化）");
            reportTypeDic.Add("P", "区域外刷施封卡");
            reportTypeDic.Add("Q", "区域外刷解封卡 ");
            reportTypeDic.Add("R", "区域内按键解封");
            reportTypeDic.Add("S", "区域外自动施封");
            reportTypeDic.Add("T", "区域内自动解封");
        }

        public void Init()
        {
            oilStatus.Add("01", "位置查询返回的位置信息");
            oilStatus.Add("20", "入网");
            oilStatus.Add("21", "退网");
            oilStatus.Add("80", "没意义");
            oilStatus.Add("84", "断电报警");
            oilStatus.Add("89", "GPS故障");
            oilStatus.Add("8F", "路线报警(出)");
            oilStatus.Add("93", "ACC打开");
            oilStatus.Add("94", "ACC关闭");
            oilStatus.Add("9E", "抢答");
            oilStatus.Add("B0", "开启铅封");
            oilStatus.Add("B1", "关闭铅封");
            oilStatus.Add("B4", "电子锁硬件故障");
            oilStatus.Add("E0", "模拟电压");
            oilStatus.Add("E1", "油量百分比");
        }

        public string getSeq()
        {
            string result = "";
            if (seq > 65534)
            {
                seq = 1;
                result = DEC_to_HEX(seq);
            }
            else
            {
                seq = seq + 1;
                result = DEC_to_HEX(seq);

            }
            return result;
        }

        /// <summary>
        /// 得到三个点组成的两个向量的弧度值
        /// </summary>
        /// <param name="pSrc">所需判定点</param>
        /// <param name="p1">点1</param>
        /// <param name="p2">点2</param>
        /// <returns></returns>
        public double getAngle(TPoint pSrc, TPoint p1, TPoint p2)
        {
            double angle = 0.0f; // 夹角

            // 向量Vector a的(x, y)坐标
            double va_x = p1.x - pSrc.x;
            double va_y = p1.y - pSrc.y;

            // 向量b的(x, y)坐标
            double vb_x = p2.x - pSrc.x;
            double vb_y = p2.y - pSrc.y;

            double productValue = (va_x * vb_x) + (va_y * vb_y);  // 向量的乘积
            double va_val = Math.Sqrt(va_x * va_x + va_y * va_y);  // 向量a的模
            double vb_val = Math.Sqrt(vb_x * vb_x + vb_y * vb_y);  // 向量b的模
            double cosValue = productValue / (va_val * vb_val);      // 余弦公式

            // aco     s的输入参数范围必须在[-1, 1]之间，否则会"domain error"
            // 对输入参数作校验和处理
            if (cosValue < -1 && cosValue > -2)
                cosValue = -1;
            else if (cosValue > 1 && cosValue < 2)
                cosValue = 1;

            // acos返回的是弧度值，转换为角度值
            angle = Math.Acos(cosValue);
            angle = Math.Abs(angle);
            if (cosValue > Math.PI)
            {
                angle = 2 * Math.PI - angle;
            }
            return angle;
        }

        /// <summary>
        /// 判定是否在区域范围内
        /// </summary>
        /// <param name="pSrc">所需判定点</param>
        /// <param name="points">点阵</param>
        /// <returns></returns>
        public bool isPtInPoly(TPoint pSrc, List<TPoint> points)
        {
            bool isInpoly = false;
            double totalAngel = 0d;
            if (points.Count() <= 2)
            {
                return isInpoly;
            }
            for (int i = 0; i < points.Count() - 1; i++)
            {
                for (int j = i; j < points.Count() - 1; j++)
                {
                    totalAngel = totalAngel + getAngle(pSrc, points[i], points[j]);
                }
            }
            if (Math.Abs(2 * Math.PI - totalAngel) < 1e-5)
            {
                isInpoly = true;
            }
            return isInpoly;
        }

        private void AddRunYWData(ModelDevice mod)
        {
            string sqlText1 = "";
            try
            {

                sqlText1 = string.Format("insert into common_data (DEVICE_ID,DEVICE_NAME,LEVEL1,LEVEL2,LEVEL3,LEVEL4,TEMPERATURE1,TEMPERATURE2,TEMPERATURE3,TEMPERATURE4,stime,cmd_type) "
                                                + " values ('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}',TO_DATE('{10}','yyyy-mm-dd hh24:mi:ss'),'{11}')",
                                                    mod.DeviceId, mod.DeviceName, mod.YW1, mod.YW2, mod.YW3, mod.YW4, mod.Temp1, mod.Temp2, mod.Temp3, mod.Temp4, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), mod.cmdType);
                int intResult1 = Common.ExecuteNonQuery(sqlText1);

                if (intResult1 >= 1)
                {
                    ShowMessageInWindow("插入成功");
                }

            }
            catch (Exception ex)
            {
                Common.WriteErrorLog(MethodBase.GetCurrentMethod().Name + "\r\n" + ex.Message + "\r\n" + sqlText1);//将出错信息写入错误日志
                ShowMessageInWindow("插入数据失败 " + ex.Message + "\r\n" + sqlText1);
            }
        }

        public class TPoint
        {
            public double x { get; set; }
            public double y { get; set; }
            public TPoint(double x, double y)
            {
                this.x = x;
                this.y = y;
            }
        }

        public class MyThreadModel
        {
            public string msg { get; set; }
            public Socket socketClient { get; set; }
        }

        /// <summary>
        /// 心跳检测方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HeartBeatCheck(object sender, EventArgs e)
        {
            // 使用线程池异步执行，避免阻塞UI线程
            ThreadPool.QueueUserWorkItem(new WaitCallback(HeartBeatCheckAsync), null);
        }
        
        /// <summary>
        /// 异步心跳检测方法
        /// </summary>
        /// <param name="state"></param>
        private void HeartBeatCheckAsync(object state)
        {
            try
            {
                List<Session> sessionsToCheck = new List<Session>();
                DateTime now = DateTime.Now;
                
                // 收集需要心跳检测的会话
                lock (locker)
                {
                    foreach (var kvp in serverSessionPool)
                    {
                        Session session = kvp.Value;
                        if (session != null && session.SockeClient != null && session.SockeClient.Connected)
                        {
                            // 如果设备已经识别（有RtuId），则进行心跳检测
                            if (!string.IsNullOrEmpty(session.RtuId))
                            {
                                sessionsToCheck.Add(session);
                            }
                        }
                    }
                }
                
                // 对每个会话进行心跳检测
                foreach (Session session in sessionsToCheck)
                {
                    try
                    {
                        // 检查是否需要发送心跳
                        TimeSpan timeSinceLastHeartBeat = now - session.LastHeartBeatTime;
                        TimeSpan timeSinceLastData = now - session.LastRecDataTime;
                        
                        // 如果超过3分钟没有收到数据，且超过2分钟没有发送心跳，则发送心跳
                        if (timeSinceLastData.TotalMinutes > 3 && timeSinceLastHeartBeat.TotalMinutes > 2)
                        {
                            SendHeartBeat(session);
                        }
                        
                        // 如果心跳失败次数过多，关闭连接
                        if (session.HeartBeatFailCount > 3)
                        {
                            ShowMessageInWindow($"设备{session.DeviceName}({session.IP})心跳失败次数过多，关闭连接");
                            SafeClose(session.SockeClient);
                            removeSocketClient(session.SockeClient.Handle);
                        }
                    }
                    catch (Exception ex)
                    {
                        ShowMessageInWindow($"心跳检测异常：{session.DeviceName} - {ex.Message}");
                        Common.WriteErrorLog($"心跳检测异常：{ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                ShowMessageInWindow("心跳检测总体异常：" + ex.Message);
                Common.WriteErrorLog("心跳检测总体异常：" + ex.Message);
            }
        }
        
        /// <summary>
        /// 发送心跳包
        /// </summary>
        /// <param name="session"></param>
        private void SendHeartBeat(Session session)
        {
            try
            {
                if (session == null || session.SockeClient == null || !session.SockeClient.Connected)
                {
                    return;
                }
                
                // 构造心跳包 - 这里使用查询基本参数作为心跳包
                string rtuId = session.RtuId;
                string cmdReportId = "FFFF"; // 心跳包的报告ID
                string cmdMessage = "00"; // 简单的心跳消息
                int messageLen = cmdMessage.Replace(" ", "").Length / 2;
                string cmdFull = "";
                int reportId = Convert.ToInt32(cmdReportId, 16);
                cmdFull = "03 12" + DEC_to_HEX(messageLen.ToString()) + rtuId + DEC_to_HEX(reportId);
                cmdFull = cmdFull + cmdMessage;
                cmdFull = cmdFull + SunCheck(cmdFull);
                cmdFull = cmdFull.Replace("7E", "7D02").Replace("7D", "7D01");
                cmdFull = "7E" + cmdFull + "7E";
                
                byte[] data = Common.HexStringToByteArray(cmdFull);
                cmdFull = Common.ByteArrayToHexString(data, 0, data.Length);
                
                // 发送心跳包
                Send(session.SockeClient, data, session.IP);
                
                // 更新心跳时间
                session.LastHeartBeatTime = DateTime.Now;
                
                ShowMessageInWindow($"发送心跳包给设备：{session.DeviceName}({session.IP})");
            }
            catch (Exception ex)
            {
                ShowMessageInWindow($"发送心跳包失败：{session.DeviceName} - {ex.Message}");
                Common.WriteErrorLog($"发送心跳包失败：{ex.Message}");
                
                // 增加心跳失败计数
                session.HeartBeatFailCount++;
            }
        }

    }
}
